GHSA-rfr2-mq9m-x2qx: datamodel-code-generator vulnerable to SSRF via --url: no host/IP validation, follows redirects
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
Details
Original advisory: https://github.com/advisories/GHSA-rfr2-mq9m-x2qx
Exploitation outlook
EPSS (FIRST.org) estimates each CVE’s probability of exploitation in the next 30 days — here is the CSIRTS.com read on those numbers.
- Low exploitation riskCVE-2026-546910.21% 30-day exploitation probability — currently an unlikely target, but scores change as exploit code circulates. Riskier than 11% of all scored CVEs.
Referenced CVEs
| CVE | CSIRTS overview | External |
|---|---|---|
| CVE-2026-54691 | coverage & exploitation status | NVD · CVE.org |
Same CVEs, other sources
How other CERTs, PSIRTs and databases cover the vulnerabilities in this advisory.
More from GitHub Security Advisories
- mediumGHSA-jr6p-8pjj-mfx6: Capsule has an incomplete fix of CVE-2026-22872: TenantResource RawItems and Generators s…2026-07-31
- mediumGHSA-68cj-mvg9-rgm2: Capsule: CapsuleConfiguration NodeMetadata regex fields lack webhook validation, allowing…2026-07-31
- mediumGHSA-ff84-5f28-78qj: re2: Out-of-bounds heap read in `exec`/`test`/`match` via attacker-influenced `lastIndex`…2026-07-31
- mediumGHSA-6hxr-mr5r-9836: re2: Global `String.prototype.match` with an empty-matchable pattern never advances → inf…2026-07-31
- mediumGHSA-x83g-979r-f5fh: Sylius Mollie Plugin has unauthenticated IDOR that leaks order token and customer PII2026-07-31