GHSA-Q2XC-RRXJ-58X9
Vulnerability from github – Published: 2026-10-08 17:16 – Updated: 2026-10-08 17:16Summary
The Pydantic AI development web chat UI (Agent.to_web(), clai web) does not validate the Host header of incoming requests. A website a developer visits can use DNS rebinding to make requests to a chat UI running on that developer's machine appear same-origin to the browser, causing the served agent to run and to execute its tools with the privileges and credentials of the local process.
Details
Once a name the attacker controls resolves to the loopback address, the browser treats the request as same-origin, so neither an Origin check nor a CSRF token constrains it — a same-origin page can read the served UI and any token in it.
Binding the web UI to localhost — the default — does not prevent this.
Impact
Applications and developers serving an agent through Agent.to_web() or clai web. The consequences depend on the tools the served agent exposes, and can include data disclosure as well as unwanted tool side effects.
Current browser protections reduce but do not remove this exposure: Chromium's Local Network Access gates loopback subresource requests, but does not cover top-level navigations, and Safari does not implement it.
Mitigation
Upgrade to pydantic-ai/pydantic-ai-slim >= 2.30.0, or >= 1.107.5 on the v1 maintenance line.
The fix validates the Host header and rejects anything other than localhost, a loopback/LAN IP address, or an explicitly allowed host, responding 421 Misdirected Request otherwise. If you serve the web chat UI under a real hostname — behind a reverse proxy, tunnel, or similar — name it explicitly:
app = agent.to_web(allowed_hosts=['ui.example.com'])
{
"affected": [
{
"package": {
"ecosystem": "PyPI",
"name": "pydantic-ai"
},
"ranges": [
{
"events": [
{
"introduced": "1.34.0"
},
{
"fixed": "1.107.5"
}
],
"type": "ECOSYSTEM"
}
]
},
{
"package": {
"ecosystem": "PyPI",
"name": "pydantic-ai"
},
"ranges": [
{
"events": [
{
"introduced": "2.0.0b1"
},
{
"fixed": "2.30.0"
}
],
"type": "ECOSYSTEM"
}
]
},
{
"package": {
"ecosystem": "PyPI",
"name": "pydantic-ai-slim"
},
"ranges": [
{
"events": [
{
"introduced": "1.34.0"
},
{
"fixed": "1.107.5"
}
],
"type": "ECOSYSTEM"
}
]
},
{
"package": {
"ecosystem": "PyPI",
"name": "pydantic-ai-slim"
},
"ranges": [
{
"events": [
{
"introduced": "2.0.0b1"
},
{
"fixed": "2.30.0"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2026-107292"
],
"database_specific": {
"cwe_ids": [
"CWE-346",
"CWE-350"
],
"github_reviewed": true,
"github_reviewed_at": "2026-10-08T17:16:39Z",
"nvd_published_at": null,
"severity": "MODERATE"
},
"details": "### Summary\n\nThe Pydantic AI development web chat UI (`Agent.to_web()`, `clai web`) does not validate the `Host` header of incoming requests. A website a developer visits can use DNS rebinding to make requests to a chat UI running on that developer\u0027s machine appear same-origin to the browser, causing the served agent to run and to execute its tools with the privileges and credentials of the local process.\n\n### Details\n\nOnce a name the attacker controls resolves to the loopback address, the browser treats the request as same-origin, so neither an `Origin` check nor a CSRF token constrains it \u2014 a same-origin page can read the served UI and any token in it.\n\nBinding the web UI to localhost \u2014 the default \u2014 does not prevent this.\n\n### Impact\n\nApplications and developers serving an agent through `Agent.to_web()` or `clai web`. The consequences depend on the tools the served agent exposes, and can include data disclosure as well as unwanted tool side effects.\n\nCurrent browser protections reduce but do not remove this exposure: Chromium\u0027s Local Network Access gates loopback subresource requests, but does not cover top-level navigations, and Safari does not implement it.\n\n### Mitigation\n\nUpgrade to `pydantic-ai`/`pydantic-ai-slim` \u003e= 2.30.0, or \u003e= 1.107.5 on the v1 maintenance line.\n\nThe fix validates the `Host` header and rejects anything other than localhost, a loopback/LAN IP address, or an explicitly allowed host, responding `421 Misdirected Request` otherwise. If you serve the web chat UI under a real hostname \u2014 behind a reverse proxy, tunnel, or similar \u2014 name it explicitly:\n\n```python\napp = agent.to_web(allowed_hosts=[\u0027ui.example.com\u0027])\n```",
"id": "GHSA-q2xc-rrxj-58x9",
"modified": "2026-10-08T17:16:39Z",
"published": "2026-10-08T17:16:39Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/pydantic/pydantic-ai/security/advisories/GHSA-q2xc-rrxj-58x9"
},
{
"type": "WEB",
"url": "https://github.com/pydantic/pydantic-ai/pull/7437"
},
{
"type": "WEB",
"url": "https://github.com/pydantic/pydantic-ai/pull/7438"
},
{
"type": "WEB",
"url": "https://github.com/pydantic/pydantic-ai/commit/394cc1d31656620704a703a2daed752afa5135fe"
},
{
"type": "WEB",
"url": "https://github.com/pydantic/pydantic-ai/commit/871c7aeec5dfed2138655ccbccbf15c6d763bae7"
},
{
"type": "PACKAGE",
"url": "https://github.com/pydantic/pydantic-ai"
},
{
"type": "WEB",
"url": "https://github.com/pydantic/pydantic-ai/releases/tag/v1.107.5"
},
{
"type": "WEB",
"url": "https://github.com/pydantic/pydantic-ai/releases/tag/v2.30.0"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:H/PR:N/UI:R/S:U/C:L/I:H/A:L",
"type": "CVSS_V3"
}
],
"summary": "Pydantic AI Web chat UI (`Agent.to_web()`, `clai web`): the local chat endpoint does not validate the `Host` header"
}
Sightings
| Author | Source | Type | Date | Other |
|---|
Nomenclature
- Seen: The vulnerability was mentioned, discussed, or observed by the user.
- Confirmed: The vulnerability has been validated from an analyst's perspective.
- Published Proof of Concept: A public proof of concept is available for this vulnerability.
- Exploited: The vulnerability was observed as exploited by the user who reported the sighting.
- Patched: The vulnerability was observed as successfully patched by the user who reported the sighting.
- Not exploited: The vulnerability was not observed as exploited by the user who reported the sighting.
- Not confirmed: The user expressed doubt about the validity of the vulnerability.
- Not patched: The vulnerability was not observed as successfully patched by the user who reported the sighting.
The approach is described in our paper Mapping CVEs to MITRE ATT&CK Techniques: A Curated Gold-Set Classifier and the Limits of LLM-Assisted Label Expansion.
Browse all ATT&CK techniques and the vulnerabilities related to each.
Related by attack behaviour
Vulnerabilities whose description is nearest to this one in the vector space of the CIRCL/vulnerability-attack-technique-biencoder model. This is a similarity search over the bi-encoder space (plain cosine), not a classification, and it has no measured accuracy.