mirror of
https://github.com/Ark0N/Codeman.git
synced 2026-10-06 23:49:41 +02:00
fix(security): block DNS rebinding + cross-site CSRF + subagent-panel XSS
Adds an always-on Host-header allowlist and a cross-site Origin/CSRF guard, hardens the text/plain body parser, validates the WebSocket upgrade origin, and escapes AI-derived fields in the subagent panel. Closes the two CRITICALs and 5 HIGHs from the 2026-06-09 adversarial security review. - C1: no Host allowlist -> DNS rebinding drove the full API (RCE) on the default no-auth loopback install. New registerHostGuard rejects rebound custom domains; allows loopback, any IP literal, the bind host, *.ts.net / *.trycloudflare.com / *.cfargotunnel.com, the active managed tunnel, and CODEMAN_ALLOWED_HOSTS. - C2: a global text/plain parser JSON-parsed every body, enabling cross-site simple-request CSRF. Parser now keeps the raw string; /api/crash-diag self-parses; the global Origin guard rejects cross-site state changes. - H1/H3/H6: self-update, session create/input, and settings/tunnel toggles were CSRF-triggerable -> now covered by the Origin guard. - H4: the subagent activity panel injected raw AI tool names/inputs into innerHTML (executed under CSP 'unsafe-inline'). All sinks now escapeHtml'd. - H5: the WebSocket upgrade had no Origin/Host check (CSWSH) -> now validated. A missing Origin is allowed so curl/CLI and Claude Code hooks keep working; custom reverse-proxy domains need CODEMAN_ALLOWED_HOSTS=host,.suffix. Deferred: H2 (self-update tag signing, needs signing infra) and CSP 'unsafe-inline' removal (needs a nonce migration). Tests: test/network-host-guard.test.ts (19), test/routes/ws-routes.test.ts updated. Report: docs/reports/security-review-2026-06-09.md Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -84,7 +84,7 @@ describe('ws-routes', () => {
|
||||
await app.register(fastifyWebsocket);
|
||||
|
||||
ctx = createMockRouteContext({ sessionId: 'ws-test-session' });
|
||||
registerWsRoutes(app, ctx as never);
|
||||
registerWsRoutes(app, ctx as never, () => ({ bindHost: '127.0.0.1', allowedHosts: [], tunnelHost: null }));
|
||||
|
||||
await app.listen({ port: PORT, host: '127.0.0.1' });
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user