PT-2026-65651 · Pypi · Datamodel-Code-Generator
Published
2026-07-28
·
Updated
2026-07-28
CVSS v3.1
8.2
High
| Vector | AV:N/AC:L/PR:N/UI:R/S:C/C:H/I:L/A:N |
Summary
JSON-Schema
$ref values pointing at HTTP or HTTPS URLs are silently dereferenced by datamodel-code-generator with no IP/host validation, no scheme allow-list, and redirects followed unconditionally. The --allow-remote-refs gate added in 0.56.0 defaults to None, which only emits a deprecation warning and then fetches the URL anyway; only explicit --allow-remote-refs=false blocks the request. The fetched body is parsed as a sub-schema and reflected verbatim into the generated .py source. As a result, any JSON-Schema document the developer feeds to datamodel-codegen — including documents authored by an attacker — can pivot to arbitrary internal addresses and leak the response into the generated code, with no developer cooperation beyond running the tool.Details
Sink:
src/datamodel code generator/parser/jsonschema.py, get ref body (lines 4776–4793, at tag 0.60.1 / commit a321547e):python
def get ref body(self, resolved ref: str) -> dict[str, YamlValue]:
if is url(resolved ref):
if not resolved ref.startswith("file://") and self.http local ref path is None:
if self.allow remote refs is False:
raise Error(f"Fetching remote $ref is disabled: {resolved ref}...")
if self.allow remote refs is None:
warn deprecated( # (A) warn only
"behavior.remote-ref-default",
details=f"Reference: {resolved ref}",
stacklevel=2,
)
return self. get ref body from url(resolved ref) # (B) fetch fires
return self. get ref body from remote(resolved ref)- (A) emits a deprecation warning when
allow remote refsis its default (None); execution falls through to (B). - (B) routes the URL through
get text from url→get body, the same fetcher described in other report — no IP validation, redirects followed.
The fetched body is then parsed as a sub-schema and merged into the model graph, so
description, title, properties, etc. from the remote document end up in the generated .py source.Only affects users who installed the
[http] extra (pip install 'datamodel-code-generator[http]').PoC
A self-contained one-file PoC is available here: https://gist.github.com/thegr1ffyn/562a6972d7dc3f2869458ae93fc608c0
Impact
Who is impacted. Anyone running
datamodel-codegen on a JSON-Schema or OpenAPI document of uncertain provenance, with the [http] extra installed. Real-world scenarios:- Trojaned OpenAPI document. A public REST API publishes
openapi.yaml. One$refpoints athttp://169.254.169.254/latest/meta-data/iam/security-credentials/<role>; runningdatamodel-codegenagainst the spec from an EC2 instance leaks the IAM credentials into the generated client. - Customer-supplied JSON Schema. A B2B SaaS auto-generates client code from customer-uploaded schemas. The customer adds an HTTP
$reftohttp://internal-admin:8080/users.json; the response (e.g. JSON user list) ends up in the generated Python the SaaS hands back to the customer. - CI on a private network. A PR adds
schemas/inbound.jsonwith an HTTP$refpointed at a service reachable only from the CI cluster's VPC; the CI runner fetches it and the generated.pyleaks the response in PR artifacts.
Higher real-world risk than the sibling CLI-flag SSRF (other SSRF in this report bundle) because the schema author chooses the destination — the developer doesn't have to type any URL.
Suggested fix.
- Flip the default in
parser/base.py:allow remote refs: bool = False, and remove the silent-fetch-with-warning fallback atparser/jsonschema.py:4786-4791. - When fetching is allowed, apply the same IP/host validation proposed for other submitted SSRF report to both the initial
$refURL and every redirect target. - Document HTTP
$refin a third-party schema as equivalent to runningcurlon the developer's host.
Maintainer resolution
This
$ref report is fixed by the same shared HTTP fetcher hardening that resolved GHSA-rfr2-mq9m-x2qx. The code landed through the GHSA-rfr2 private security PR koxudaxi/datamodel-code-generator-ghsa-rfr2-mq9m-x2qx#1 and was merged into the public repository as 5fdba4a09f2d7a9996a504975b7ef7d63e3715bb. Follow-up generated-file and coverage fixes were merged in koxudaxi/datamodel-code-generator#3279 and docs were synced in #3280. The patched release is 0.61.0.No separate net code diff remains in the GHSA-954 private PR because the shared HTTP fetcher patch is already present on
main. This advisory remains separate because the affected entry point is remote JSON Schema/OpenAPI $ref resolution rather than direct CLI --url input.The fix does not flip the
--allow-remote-refs compatibility default in this patch. Instead, it mitigates the SSRF issue by blocking localhost, loopback, private, link-local, reserved, and other non-public network targets by default, validating every redirect target before it is fetched, and requiring --allow-private-network / allow private network=True for trusted internal schema endpoints. Remote $ref fetching remains controlled by --allow-remote-refs; non-public/internal targets additionally require --allow-private-network.Submitted by: Hamza Haroon (thegr1ffyn)
Fix
SSRF
Found an issue in the description? Have something to add? Feel free to write us 👾
Weakness Enumeration
Related Identifiers
Affected Products
Datamodel-Code-Generator