[object Object]

← back to Wallco Ai

security parity with starsofdesign: app.disable(x-powered-by), rate-limit 60/min/IP on /api/studio/*, COOP header at nginx

c82055d596645f19821cb99cd8aafbde5cc9125b · 2026-05-12 09:55:19 -0700 · SteveStudio2

Files touched

Diff

commit c82055d596645f19821cb99cd8aafbde5cc9125b
Author: SteveStudio2 <stevestudio2@SteveStacStudio.lan>
Date:   Tue May 12 09:55:19 2026 -0700

    security parity with starsofdesign: app.disable(x-powered-by), rate-limit 60/min/IP on /api/studio/*, COOP header at nginx
---
 package-lock.json | 28 ++++++++++++++++++++++++++++
 package.json      |  1 +
 server.js         | 10 ++++++++++
 3 files changed, 39 insertions(+)

diff --git a/package-lock.json b/package-lock.json
index 09baf00..b710c00 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -13,6 +13,7 @@
         "compression": "^1.8.1",
         "dotenv": "^17.4.2",
         "express": "^5.2.1",
+        "express-rate-limit": "^8.5.1",
         "jsonwebtoken": "^9.0.3"
       }
     },
@@ -371,6 +372,24 @@
         "url": "https://opencollective.com/express"
       }
     },
+    "node_modules/express-rate-limit": {
+      "version": "8.5.1",
+      "resolved": "https://registry.npmjs.org/express-rate-limit/-/express-rate-limit-8.5.1.tgz",
+      "integrity": "sha512-5O6KYmyJEpuPJV5hNTXKbAHWRqrzyu+OI3vUnSd2kXFubIVpG7ezpgxQy76Zo5GQZtrQBg86hF+CM/NX+cioiQ==",
+      "license": "MIT",
+      "dependencies": {
+        "ip-address": "^10.2.0"
+      },
+      "engines": {
+        "node": ">= 16"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/express-rate-limit"
+      },
+      "peerDependencies": {
+        "express": ">= 4.11"
+      }
+    },
     "node_modules/finalhandler": {
       "version": "2.1.1",
       "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-2.1.1.tgz",
@@ -534,6 +553,15 @@
       "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
       "license": "ISC"
     },
+    "node_modules/ip-address": {
+      "version": "10.2.0",
+      "resolved": "https://registry.npmjs.org/ip-address/-/ip-address-10.2.0.tgz",
+      "integrity": "sha512-/+S6j4E9AHvW9SWMSEY9Xfy66O5PWvVEJ08O0y5JGyEKQpojb0K0GKpz/v5HJ/G0vi3D2sjGK78119oXZeE0qA==",
+      "license": "MIT",
+      "engines": {
+        "node": ">= 12"
+      }
+    },
     "node_modules/ipaddr.js": {
       "version": "1.9.1",
       "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz",
diff --git a/package.json b/package.json
index 8a60518..a73d7db 100644
--- a/package.json
+++ b/package.json
@@ -15,6 +15,7 @@
     "compression": "^1.8.1",
     "dotenv": "^17.4.2",
     "express": "^5.2.1",
+    "express-rate-limit": "^8.5.1",
     "jsonwebtoken": "^9.0.3"
   }
 }
diff --git a/server.js b/server.js
index 3e0eb81..2aabe2a 100644
--- a/server.js
+++ b/server.js
@@ -93,6 +93,16 @@ try { require('./src/chat').mount(app); console.log('  Chat layer mounted'); } c
 // ── Review layer: sliders + chips + chip-chat on /designs (admin-gated by hostname/query)
 try { require('./src/review').mount(app, () => DESIGNS); } catch (e) { console.error('Review mount failed:', e.message); }
 
+// Drop the Express version disclosure header (info-leak hardening per starsofdesign security audit 2026-05-12)
+app.disable('x-powered-by');
+
+// Rate limit the expensive AI endpoints (generation/compose/upload hit LLMs + Replicate)
+// 60 req/min/IP across /api/studio/* prevents a single bad actor from burning credits.
+try {
+  const rateLimit = require('express-rate-limit');
+  app.use('/api/studio', rateLimit({ windowMs: 60_000, max: 60, standardHeaders: 'draft-7', legacyHeaders: false }));
+} catch (_) { /* express-rate-limit not installed — non-fatal */ }
+
 // ── Admin layer: vendor browse + aesthetic search + inspiration pool (NO-LEAK — admin only)
 try { require('./src/admin').mount(app); console.log('  Admin layer mounted'); } catch (e) { console.error('Admin mount failed:', e.message); }
 

← b03add3 wallco.ai · home gets a 'Stumble through the catalog' random  ·  back to Wallco Ai  ·  wallco.ai · /api/me/saved bulk endpoint + ♥ saved badges in 0fccfb6 →