Skip to content

[red-team] Sprint 1 — MCP exec & CSRF boundary (P0: consent-before-spawn, Origin allow-list) #87

Description

@Santisoutoo

Part of VforVitorio#884 (Fable-5 red-team audit 2026-07-05). Sprint 1 — MCP exec & CSRF boundary (P0). The headline: unauthenticated MCP-server registration whose command is later spawned, reachable as CSRF→RCE from the browser (and direct unauth RCE if ever networked). Full trace in memory/fable_redteam_audit_2026-07-05.md (issue text kept non-exploitable).

⚠️ Unpatched RCE on a public repo — consider a private GitHub Security Advisory for this sprint.

  • S1.1 security(mcp): consent-before-spawn for external MCP servers (no auto-connect) [M] [P0] — an added/imported server's command string is spawned as a stdio subprocess on the first GET /api/v1/mcp/tools (chat/mcp_client.py:26-28,102-124,182-211); command/args have NO allow-list (api/routers/mcp_servers.py:107; mcp_servers/schemas.py:69-98 validates only url); the .mcpb bundle path is api/routers/mcp_servers.py:248 + mcp_servers/bundle.py:226-251. AC: require explicit in-SPA user consent before the FIRST spawn of any newly added/imported server; never auto-connect on add/import. (P0-1, RCE)
  • S1.2 security(api): Origin/Host allow-list on state-changing + spawn-triggering routes [M] [P0] — only RequestIdMiddleware is installed; no auth/CSRF gate anywhere (api/app.py:129). The browser-reachable subset — bodyless POST /sync, POST /system/semantic-install, GET /mcp/tools, multipart POST /mcp/bundles (multipart = CORS "simple request", no preflight) — is CSRF-able. AC: reject cross-origin state-changing requests via an Origin/Host allow-list (or a required custom header the SPA sets). (P0/P1-2)
  • S1.3 security(deploy): assert + document the 127.0.0.1 bind as a hard security boundary [S]main.py:9. AC: startup assertion / explicit opt-in + loud warning when bound off-loopback; require real auth before any networked/multi-user mode; note in packaging ([epic] Legal chat — trust & UX (Fable 5 audit) #37) + CONTRIBUTING. (P0/P1-2)
  • S1.4 security(mcp): sandbox spawned MCP servers (stretch, defense-in-depth) [S] — the _build_config seam at chat/mcp_client.py:127 is already flagged for this. (P0-1)

Full detail: memory/fable_redteam_audit_2026-07-05.md.


Upstream: VforVitorio#885

Metadata

Metadata

Assignees

No one assigned

    Labels

    area: chatChatbot / MCP toolsbugSomething isn't working

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions