MCP Python SDK: Unbounded Session Accumulation in StreamableHTTP Transport Enables Resource ExhaustionGHSA-84m7-p3x7-pcfv
HIGHFix: modelcontextprotocol/python-sdk#3395GHSA-84m7-p3x7-pcfv is a high-severity (CVSS 7.5) Uncontrolled Resource Consumption vulnerability in mcp. A fix is available for mcp — see the affected versions and patch details below.
Exploitation Status
No confirmed exploitation observed yet
- CISA assesses this as automatable — exploitation doesn’t require manual, per-target effort, which raises the odds of mass scanning and opportunistic attacks.
- CISA’s own triage has not observed active exploitation or public proof-of-concept code for this CVE as of its last assessment.
Exploitation and automatability from CISA’s SSVC triage for GHSA-84m7-p3x7-pcfv.
EPSS Exploitation Probability
Probability of exploitation in the next 30 days, from FIRST.org EPSS.
How urgent is this, really
GHSA-84m7-p3x7-pcfv by exploitation likelihood (EPSS) against impact (CVSS). Outside the shaded patch-first corner.
Where this sits among everything scored
Of 394,415 CVEs with a current EPSS score, this one falls in the < 10% band (highlighted). Counts from FIRST.org, log-scaled.
Real-World Exposure
mcp🐍mcpReal-time download stats are indexed for npm and PyPI packages. This vulnerability affects PyPI packages — download data is not available via public APIs for these ecosystems.
Description
Summary
In affected versions, a Streamable HTTP server in stateful mode (the default) never reclaimed session state:
- sessions did not expire;
- a client
DELETEended the session but left its entry registered; - a session whose first request was refused stayed registered with a running task.
Each session also kept its parsed initialize parameters, and the number of sessions was unlimited. A client that could reach the endpoint could grow server memory without bound using ordinary short requests; only a restart reclaimed it.
Am I affected?
Yes, if you serve MCP over Streamable HTTP in stateful mode and clients you do not fully trust can reach the endpoint. Stateful mode is the default for:
FastMCP(1.x)MCPServerandServer.streamable_http_app()(2.x)StreamableHTTPSessionManager
Affected versions: 1.8.0 through 1.29.1, and 2.0.0 through 2.1.1.
Not affected:
- servers on 1.12.0 or later passing
stateless_http=True(no sessions are kept) - servers using only the stdio or SSE transports
Authentication limits who can open sessions, not how many a token holder can open.
Fix
Upgrade to mcp 1.30.0 (1.x) or 2.2.0 (2.x) or later. In those versions:
- a session with no request in flight for
session_idle_timeoutseconds (default 1800) is closed and its ID then answers404; open streams and in-progress requests keep it alive; - at most
max_sessionssessions exist at once (default 10000); a request that would open another is answered503; - a session is discarded as soon as it ends, whether by
DELETE, expiry, or a refused opening request.
Both settings are keyword arguments on FastMCP(...) (1.x), MCPServer.run() / streamable_http_app() (2.x) and StreamableHTTPSessionManager; None disables them.
This bounds retention rather than eliminating it: a live session still holds its initialize parameters (up to roughly twice the 4 MiB body limit), and an initialize with invalid parameters still opens a session that expires like any other. On a small host, lower session_idle_timeout, max_sessions and max_request_body_size to fit.
If you cannot upgrade yet, pass stateless_http=True (1.12.0 or later) where you need no per-session state, or restrict who can reach the endpoint.
Affected Packages
| Ecosystem | Package | Vulnerable range | Fix |
|---|---|---|---|
| 🐍PyPI | mcp | ≥ 1.8.0&&< 1.30.0 | 1.30.0pip install --upgrade 'mcp==1.30.0' |
| 🐍PyPI | mcp | ≥ 2.0.0&&< 2.2.0 | 2.2.0pip install --upgrade 'mcp==2.2.0' |
Detection & mitigation playbook
Open-source dependencyDetect
Scan your dependency tree (package-lock.json, pnpm-lock.yaml, requirements.txt, go.sum, etc.) for mcp, including transitive dependencies — a direct dependency you never call can still pull in a vulnerable version.
Fix
Update mcp to 1.30.0 or later, then make sure no transitive (indirect) dependency still pins the vulnerable range — O3 confirms GHSA-84m7-p3x7-pcfv is resolved across your whole dependency graph.
Workarounds
Cap what an attacker can consume: apply request size, rate and timeout limits in front of the affected component, and run it with memory and CPU limits so exhaustion degrades one worker rather than the whole service.
Frequently Asked Questions
Is GHSA-84m7-p3x7-pcfv in your dependencies?
Find it across PyPI, including transitive dependencies.