[object Object]

← 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 →