From 215ccd1a38b6c68fd781ccb0a1d7bda10cfdbfa8 Mon Sep 17 00:00:00 2001 From: James Couch Date: Fri, 6 Feb 2026 02:40:23 -0700 Subject: [PATCH] Add security headers to mabp-dashboard and mabp-api - mabp-dashboard: HSTS, X-Frame-Options DENY, nosniff, CSP, Referrer-Policy, reject non-GET/HEAD with 405 - mabp-api: disable x-powered-by, add security headers middleware, limit JSON body to 64kb Co-Authored-By: Claude Opus 4.6 --- mabp-api/index.js | 14 +++++++++++++- mabp-dashboard/server.js | 19 +++++++++++++++++-- 2 files changed, 30 insertions(+), 3 deletions(-) diff --git a/mabp-api/index.js b/mabp-api/index.js index 7b968db..aa044a0 100644 --- a/mabp-api/index.js +++ b/mabp-api/index.js @@ -3,8 +3,20 @@ const cors = require('cors'); const marketplaceRouter = require('./marketplace-aggregator'); const app = express(); +app.disable('x-powered-by'); app.use(cors()); -app.use(express.json()); +app.use(express.json({ limit: '64kb' })); +app.use((req, res, next) => { + res.set({ + 'Strict-Transport-Security': 'max-age=63072000; includeSubDomains', + 'X-Frame-Options': 'DENY', + 'X-Content-Type-Options': 'nosniff', + 'Referrer-Policy': 'strict-origin-when-cross-origin', + 'X-XSS-Protection': '0', + 'Content-Security-Policy': "default-src 'self'" + }); + next(); +}); // Mount marketplace aggregator app.use('/api/marketplace', marketplaceRouter); diff --git a/mabp-dashboard/server.js b/mabp-dashboard/server.js index c9a32b3..3352fd2 100644 --- a/mabp-dashboard/server.js +++ b/mabp-dashboard/server.js @@ -4,12 +4,27 @@ const path = require('path'); const PORT = 5050; +const securityHeaders = { + 'Strict-Transport-Security': 'max-age=63072000; includeSubDomains', + 'X-Frame-Options': 'DENY', + 'X-Content-Type-Options': 'nosniff', + 'Content-Security-Policy': "default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'", + 'Referrer-Policy': 'strict-origin-when-cross-origin', + 'X-XSS-Protection': '0' +}; + const server = http.createServer((req, res) => { + if (req.method !== 'GET' && req.method !== 'HEAD') { + res.writeHead(405, { ...securityHeaders, 'Allow': 'GET, HEAD' }); + res.end('Method Not Allowed'); + return; + } + if (req.url === '/' || req.url === '/index.html') { - res.writeHead(200, { 'Content-Type': 'text/html' }); + res.writeHead(200, { ...securityHeaders, 'Content-Type': 'text/html' }); res.end(fs.readFileSync(path.join(__dirname, 'index.html'))); } else { - res.writeHead(404); + res.writeHead(404, securityHeaders); res.end('Not found'); } });