Skip to content

Error response bodies are read without a size cap #546

Description

@alistair3149

fetchCore reads the whole body of any non-2xx response into memory at src/transport/httpFetch.ts:128:

const errorBody = await finalResponse.text().catch(() => '');

No cap applies. The byte limits callers pass are enforced on the success path only, and node-fetch's own size option is left at its default of 0, which means unlimited. So a source that answers a rejected request with a multi-megabyte error page — a gateway HTML dump, a stack trace, a debug listing — spikes the heap by the full body size, however small a limit the caller asked for.

The destination is caller-supplied in every *-from-url tool, and the guard that stops those URLs reaching private addresses does not bound what a public one returns.

Reproduced against a loopback server answering 500 with a 5 MB body, while asking for a 3-byte cap:

PROBE 2 (non-2xx body read):
  status: 500 | bytes buffered: 5000000

The whole body is buffered to build a message that quotes a few hundred characters of it.

AI-authored — Claude Code, Opus 5 (xhigh); filed at @alistair3149's request following a code review; not yet human-reviewed; reproduced locally against a loopback server, output above.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions