← back to Wallco Ai
Gate /admin/golive[.json] + /api/dw-textures (unauth shell-exec + vendor leak)
03774407ad35efe2b256d893ffbfe3e14c1913e2 · 2026-05-26 10:51:27 -0700 · Steve Abrams
/admin/golive.json ran execSync(node scripts/golive_status.js) with no auth
gate — unauthenticated shell-exec reachable on the live site. /admin/golive
rendered the checklist unauthed. /api/dw-textures returned vendor names
(Thibaut/Koroseal) in public JSON, bypassing the dropdown denylist. All three
now require isAdmin(req) → 404, matching the canonical gate pattern. Local fix
only; deploy is Steve-gated.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Files touched
Diff
commit 03774407ad35efe2b256d893ffbfe3e14c1913e2
Author: Steve Abrams <steve@designerwallcoverings.com>
Date: Tue May 26 10:51:27 2026 -0700
Gate /admin/golive[.json] + /api/dw-textures (unauth shell-exec + vendor leak)
/admin/golive.json ran execSync(node scripts/golive_status.js) with no auth
gate — unauthenticated shell-exec reachable on the live site. /admin/golive
rendered the checklist unauthed. /api/dw-textures returned vendor names
(Thibaut/Koroseal) in public JSON, bypassing the dropdown denylist. All three
now require isAdmin(req) → 404, matching the canonical gate pattern. Local fix
only; deploy is Steve-gated.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
---
server.js | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/server.js b/server.js
index 525a950..d137de4 100644
--- a/server.js
+++ b/server.js
@@ -722,7 +722,8 @@ function sortDesigns(designs, sort) {
}
// ── Go-Live status (admin checklist)
-app.get('/admin/golive.json', async (_req, res) => {
+app.get('/admin/golive.json', async (req, res) => {
+ if (!isAdmin(req)) return res.status(404).json({ error: 'not found' });
try {
// Run the same module the CLI uses, but inline so we can stream
const { main } = require('./scripts/golive_status');
@@ -734,7 +735,8 @@ app.get('/admin/golive.json', async (_req, res) => {
}
});
-app.get('/admin/golive', (_req, res) => {
+app.get('/admin/golive', (req, res) => {
+ if (!isAdmin(req)) return res.status(404).type('html').send('<h1>404</h1>');
res.type('html').send(`<!doctype html>
<html lang="en"><head>
<meta charset="utf-8"><title>wallco.ai — Go-Live Checklist</title>
@@ -8590,6 +8592,7 @@ app.get('/api/status-browser', (req, res) => {
});
app.get('/api/dw-textures', (req, res) => {
+ if (!isAdmin(req)) return res.status(404).json({ error: 'not found' });
try {
// ALL natural-material wallcoverings across DW catalog (no brand whitelist).
// Prestige ranking puts the highest-end brands first; LIMIT 600 keeps the
← 7d8a4d5 deploy: add step 2c to ship guarded refresh_designs_snapshot
·
back to Wallco Ai
·
TODO: record 157-catalog incident + fix, fliepaper publish + 3646071 →