CVE-2026-54691
Summary
datamodel-code-generator's built-in HTTP fetcher (http.get_body) issues an httpx.GET against any URL passed to --url (or reached via a redirect chain) with **no allow-list, no deny-list, no IP/host validation, and follow_redirects=True**. Loopback addresses, RFC1918 ranges, link-local (169.254.169.254 cloud metadata), unique-local IPv6 and any other network-accessible target are all reachable. The JSON/YAML response body is parsed as a schema and reflected into the generated .py source, exfiltrating the response to anyone with access to that file (commonly committed to a repository).
Details
Sink: src/datamodel_code_generator/http.py, get_body (lines 31–61, at tag 0.60.1 / commit a321547e):
def get_body(url, headers=None, ignore_tls=False,
query_parameters=None, timeout=DEFAULT_HTTP_TIMEOUT) -> str:
httpx = _get_httpx()
try:
response = httpx.get(
url,
headers=headers,
verify=not ignore_tls,
follow_redirects=True, # (A)
params=query_parameters,
timeout=timeout,
)
except Exception as e:
...
if response.status_code >= 400:
...
content_type = response.headers.get("content-type", "").lower()
if "text/html" in content_type:
raise SchemaFetchError(...) # (B) — only filter
return response.text # (C) → embedded in generated.py
- (A) follows redirects unconditionally — a public URL → 302 → internal address chain works.
- (B) the only filter is rejecting text/html. Non-HTML internal endpoints (JSON APIs, cloud metadata, admin services) pass through.
- (C) the response body becomes the schema; its title, description, properties, etc. land in the generated .py as class attributes and Field(description=...) strings.
get_body is called by parser/base.py:1326 (_get_text_from_url), which is reached from CLI argument --url <URL>. (The $ref path is a separate advisory — see GHSA-D.)
Only affects users who installed the [http] extra (pip install 'datamodel-code-generator[http]').
PoC
A self-contained one-file PoC available here:
https://gist.github.com/thegr1ffyn/18de7
⚡ Watch CVE-2026-54691
Get an email if CVE-2026-54691 is added to CISA KEV, gains public exploit code, or a new advisory cites it — max one per day, one-click unsubscribe.
Exploitation outlook
- Low exploitation risk0.21% 30-day exploitation probability — currently an unlikely target, but scores change as exploit code circulates. Riskier than 11% of all EPSS-scored CVEs.
Advisory coverage (2)
External references
Embed the live status
— this badge updates automatically when the KEV or exploit status changes. How to embed it →
[](https://www.csirts.com/cve/CVE-2026-54691)