GHSA-v2xh-2vp8-57h8
Pydantic AI: Unbounded memory use when downloading remote content via web_fetch or FileUrl
Packages
| Ecosystem | Package | Affected | Fixed in |
|---|---|---|---|
| PyPI | pydantic-ai | >= 1.77.0, < 1.107.2 | 1.107.2 |
| PyPI | pydantic-ai | >= 2.0.0b1, < 2.24.0 | 2.24.0 |
| PyPI | pydantic-ai-slim | >= 1.77.0, < 1.107.2 | 1.107.2 |
| PyPI | pydantic-ai-slim | >= 2.0.0b1, < 2.24.0 | 2.24.0 |
Details
As written in the advisory (Markdown source, shown as plain text).
### Summary
Several remote-content download paths in Pydantic AI buffered the entire HTTP response body into memory before enforcing any size limit. An application that exposes the local web-fetch tool (`web_fetch_tool`, or the `WebFetch` capability's local fallback) to untrusted prompts can be driven to fetch an attacker-chosen URL that streams a very large body, exhausting process memory and crashing the worker. The same unbounded buffering applied to `FileUrl` media downloads (`ImageUrl`, `DocumentUrl`, `VideoUrl`, `AudioUrl`).
This is an **availability** issue only. SSRF protections (scheme allowlist, private-IP and cloud-metadata blocking) are unaffected; there is no confidentiality or integrity impact.
### Details
The download helpers read the full response body before applying content-size controls, so an existing text-length limit only truncated *after* the whole body was already in memory, and media downloads had no wire-level cap at all. A single large response could grow process memory without bound .
### Who Is Affected
You are affected if your application registers the local web-fetch tool (or relies on the `WebFetch` capability's local fallback) and exposes the agent to untrusted prompts, or if it downloads large remote `FileUrl`s influenced by untrusted input. Applications that only fetch developer-controlled URLs are not exposed to the model-chosen attack path.
### Remediation
Upgrade to `2.24.0` or later (v2) or `1.107.2` or later (v1). Patched versions enforce a default 50 MiB cap on web-fetch and `FileUrl` downloads while streaming; pass `None` to the limit to restore the previous unbounded behavior.
### Credits
Identified during internal review of media-download hardening.
References
External links from the advisory. They lead to third-party sites.
- https://github.com/pydantic/pydantic-ai/security/advisories/GHSA-v2xh-2vp8-57h8
- https://github.com/pydantic/pydantic-ai/pull/7141
- https://github.com/pydantic/pydantic-ai/pull/7308
- https://github.com/pydantic/pydantic-ai/commit/7a64d049c3f5271a975cd1d64b2fa876d83ede1d
- https://github.com/pydantic/pydantic-ai/commit/e3824a58c82864ed26afb2887619834a4eb86cc8
- https://github.com/pydantic/pydantic-ai
- https://github.com/pydantic/pydantic-ai/releases/tag/v1.107.2
- https://github.com/pydantic/pydantic-ai/releases/tag/v2.24.0