Skip to content

[npm] fastmcp: Unbounded HTTP Body in Streamable HTTP Transport (CWE-770) #7292

@razashariff

Description

@razashariff

Package

  • Name: fastmcp
  • Ecosystem: npm
  • Affected versions: <= 3.35.0
  • Weekly downloads: ~263,000
  • Stars: 3,023

Vulnerability

CWE-770: Allocation of Resources Without Limits or Throttling

fastmcp's streamable HTTP transport has two body size validation failures:

  1. #handleMcpRequest (edge/index.js:511): Calls request.json() with ZERO body size validation. No Content-Length check, no body stream size tracking.

  2. Content-Length bypass (edge/index.js:232-236): The size check uses parseInt(request.headers.get('content-length') ?? '0', 10) -- when Content-Length header is missing, it defaults to '0', which passes the > MAXIMUM_MESSAGE_SIZE check. The subsequent request.json() then reads the entire unbounded body.

An attacker sends arbitrarily large POST bodies to /mcp. Tested up to 50MB per request, all accepted with status 200. Server RSS grew from 80.3MB to 463.1MB (+382.8MB) across 5 trials. No payload was ever rejected.

Validation

5/5 trials, 100% reproducibility. Every payload size (1MB, 5MB, 10MB, 50MB) accepted.
Both with and without Content-Length header -- the size check is completely ineffective.

CVSS

7.5 (High) -- AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H

Recommended Fix

Add explicit body size enforcement BEFORE calling request.json():

  • Stream the body with a size counter
  • Reject with 413 if body exceeds limit (4MB default)
  • Do NOT rely on Content-Length header alone

Credit

Raza Sharif, CyberSecAI Ltd

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions