← 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
M package-lock.jsonM package.jsonM server.js
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 →