From 2af1459d259963f559c414097c53c1ffa09ff830 Mon Sep 17 00:00:00 2001 From: Paul Huliganga Date: Mon, 30 Mar 2026 09:56:25 -0400 Subject: [PATCH] security(harness): restrict /api/harness/* routes to localhost only Add requireLocalhost middleware that returns 403 for non-localhost requests (127.0.0.1/::1 only). Prevents external access to diagnostic endpoints. --- src/backend/routes/harness.ts | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/backend/routes/harness.ts b/src/backend/routes/harness.ts index f29a7e2..da77085 100644 --- a/src/backend/routes/harness.ts +++ b/src/backend/routes/harness.ts @@ -28,6 +28,17 @@ type GitCommitSummary = { relative: string; }; +function requireLocalhost(req: any, res: any, next: any) { + const ip = req.ip || (req.socket && req.socket.remoteAddress) || ''; + // Normalize IPv4-mapped IPv6 addresses (e.g., ::ffff:127.0.0.1) + const normalizedIp = ip.replace(/^::ffff:/, ''); + + if (normalizedIp !== '127.0.0.1' && normalizedIp !== '::1') { + return res.status(403).json({ success: false, error: 'Forbidden: Access to harness routes is restricted to localhost.' }); + } + next(); +} + function safeReadJson(path: string): T | null { try { if (!existsSync(path)) return null; @@ -77,6 +88,7 @@ function getLastCommit(projectRoot: string): GitCommitSummary | null { export function createHarnessRoutes(projectRoot = process.cwd()): Router { const router = Router(); + router.use(requireLocalhost); router.get('/status', (_req, res) => { try {