Files
pad/internal/server
xarmian f9de1871dd fix(server): cap the MCP request body at 7 MiB, answering 413 (BUG-3534) (#1988)
* fix(server): cap the MCP request body at 7 MiB, answering 413 (BUG-3534)

The MCP transport (mcp-go's StreamableHTTPServer) reads a POST body
whole into memory and has no cap of its own, so any caller, before auth,
could make the server buffer any amount. Both MCP mounts now refuse a
body over max(3 x the 2 MiB JSON cap, 6 x the artifact import cap) +
1 MiB with 413 and a JSON-RPC error, before auth and before anything
reads the body. A declared length is checked without a read; a chunked
body is read up to the limit and replayed.

The bound is derived: every tools/call's payload lands in a downstream
request already capped at 2 MiB of JSON (up to 3x once a client
\u-escapes it) or in an artifact (up to 6x as control characters
inside a JSON string), so no call that could otherwise succeed is
refused. It follows PAD_IMPORT_ARTIFACT_MAX_BYTES.

A sweep of every request-body reader (the body-reader census plus every
reader outside internal/server) found mcp-go's the only uncapped one.

* fix(server): cap the MCP body after auth, so an unauthenticated body is never read (BUG-3534, codex r1)

* test(server): pin that a 413 is audited; narrow the unread claims to the limiter (BUG-3534, codex r2)
2026-10-09 19:48:36 -04:00
..