CVE-2026-54690
datamodel-code-generator vulnerable to SSRF via JSON-Schema `$ref` to HTTP URL (silent by default)
datamodel-code-generator generates Pydantic v2 models, dataclasses, TypedDict, and msgspec.Struct from OpenAPI, JSON Schema, GraphQL, Avro, Protobuf, and raw JSON, YAML, or CSV. From 0.9.1 until 0.61.0, datamodel-code-generator silently dereferences attacker-controlled JSON Schema $ref HTTP or HTTPS URLs in src/datamodel_code_generator/parser/jsonschema.py through _get_ref_body, and the --allow-remote-refs gate can warn instead of blocking, allowing server-side request forgery through src/datamodel_code_generator/http.py. This issue is fixed in version 0.61.0.
Attack profile
How easy it is to exploit
- Attack vector
- Network
- Complexity
- Low
- Privileges needed
- None
- User interaction
- Required
What an attacker can affect
- Confidentiality
- High
- Integrity
- Low
- Availability
- None
Exploit likelihood
What each source reports
CVE List Score used
8.2
datamodel-code-generator vulnerable to SSRF via JSON-Schema `$ref` to HTTP URL (silent by default)
datamodel-code-generator generates Pydantic v2 models, dataclasses, TypedDict, and msgspec.Struct from OpenAPI, JSON Schema, GraphQL, Avro, Protobuf, and raw JSON, YAML, or CSV. From 0.9.1 until 0.61.0, datamodel-code-generator silently dereferences attacker-controlled JSON Schema $ref HTTP or HTTPS URLs in src/datamodel_code_generator/parser/jsonschema.py through _get_ref_body, and the --allow-remote-refs gate can warn instead of blocking, allowing server-side request forgery through src/datamodel_code_generator/http.py. This issue is fixed in version 0.61.0.
- Record
CVE-2026-54690- CVSS 3.1
- 8.2 High
CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:H/I:L/A:N - Weakness
- CWE-918
- Updated
- 2026-11-02
EUVDEUVD-2026-50074
8.2
datamodel-code-generator generates Pydantic v2 models, dataclasses, TypedDict, and msgspec.Struct from OpenAPI, JSON Schema, GraphQL, Avro, Protobuf, and raw JSON, YAML, or CSV. From 0.9.1 until 0.61.0, datamodel-code-generator silently dereferences attacker-controlled JSON Schema $ref HTTP or HTTPS URLs in src/datamodel_code_generator/parser/jsonschema.py through _get_ref_body, and the --allow-remote-refs gate can warn instead of blocking, allowing server-side request forgery through src/datamodel_code_generator/http.py. This issue is fixed in version 0.61.0.
- Record
EUVD-2026-50074- CVSS 3.1
- 8.2 High
CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:H/I:L/A:N - Updated
- 2026-11-02
GitHub AdvisoriesGHSA-954p-556p-r752
8.2
datamodel-code-generator vulnerable to SSRF via JSON-Schema `$ref` to HTTP URL (silent by default)
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):
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 runningcurl…
- Record
GHSA-954p-556p-r752- CVSS 3.1
- 8.2 High
CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:H/I:L/A:N - Weakness
- CWE-918
- Updated
- 2026-11-02
NVD
8.2
datamodel-code-generator generates Pydantic v2 models, dataclasses, TypedDict, and msgspec.Struct from OpenAPI, JSON Schema, GraphQL, Avro, Protobuf, and raw JSON, YAML, or CSV. From 0.9.1 until 0.61.0, datamodel-code-generator silently dereferences attacker-controlled JSON Schema $ref HTTP or HTTPS URLs in src/datamodel_code_generator/parser/jsonschema.py through _get_ref_body, and the --allow-remote-refs gate can warn instead of blocking, allowing server-side request forgery through src/datamodel_code_generator/http.py. This issue is fixed in version 0.61.0.
- Record
CVE-2026-54690- CVSS 3.1
- 8.2 High
CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:H/I:L/A:N - Weakness
- CWE-918
- Updated
- 2026-11-02
OSV
8.2
datamodel-code-generator vulnerable to SSRF via JSON-Schema `$ref` to HTTP URL (silent by default)
datamodel-code-generator generates Pydantic v2 models, dataclasses, TypedDict, and msgspec.Struct from OpenAPI, JSON Schema, GraphQL, Avro, Protobuf, and raw JSON, YAML, or CSV. From 0.9.1 until 0.61.0, datamodel-code-generator silently dereferences attacker-controlled JSON Schema $ref HTTP or HTTPS URLs in src/datamodel_code_generator/parser/jsonschema.py through _get_ref_body, and the --allow-remote-refs gate can warn instead of blocking, allowing server-side request forgery through src/datamodel_code_generator/http.py. This issue is fixed in version 0.61.0.
- Record
CVE-2026-54690- CVSS 3.1
- 8.2 High
CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:H/I:L/A:N - Weakness
- CWE-918
- Updated
- 2026-11-02
OSVGHSA-954p-556p-r752
8.2
datamodel-code-generator vulnerable to SSRF via JSON-Schema `$ref` to HTTP URL (silent by default)
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):
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 runningcurl…
- Record
GHSA-954p-556p-r752- CVSS 3.1
- 8.2 High
CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:H/I:L/A:N - Weakness
- CWE-918
- Updated
- 2026-11-02
OSVPYSEC-2026-3560
8.2
datamodel-code-generator vulnerable to SSRF via JSON-Schema `$ref` to HTTP URL (silent by default)
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):
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 runningcurl…
- Record
PYSEC-2026-3560- CVSS 3.1
- 8.2 High
CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:H/I:L/A:N - Updated
- 2026-11-02
Affected products
Affected packages
| Package | Affected | Fixed |
|---|---|---|
datamodel-code-generatorPyPI |
0.9.1 to 0.60.2 | 0.61.0 |
datamodel-code-generatorPyPI |
0.9.1 up to 0.61.0, plus listed versions 0.10.00.10.10.10.20.10.30.11.0 Show 45 moreShow less0.11.10.11.100.11.110.11.120.11.130.11.140.11.150.11.160.11.170.11.180.11.190.11.20.11.200.11.30.11.40.11.50.11.60.11.70.11.80.11.90.12.00.12.10.12.20.12.30.13.00.13.10.13.20.13.30.13.40.13.50.14.00.14.10.15.00.16.00.16.10.17.00.17.10.17.20.18.00.18.10.19.00.20.00.21.00.21.10.21.2 |
0.61.0 |
History
| Recorded | Changed | Sources |
|---|---|---|
| first indexed | CVE List, EUVD, GitHub Advisories, NVD, OSV |
Dates are when Every CVE recorded each change. Upstream dates may differ.
In short
CVE-2026-54690 is a high vulnerability (CVSS 8.2) in Koxudaxi Datamodel-code-generator, published July 28, 2026. No source lists public exploit code. EPSS puts the chance of exploitation in the next 30 days at 0.39%, the 32nd percentile. Fixed in datamodel-code-generator 0.61.0.
References
github.com/koxudaxi/datamodel-code-generator/security/advisories/GHSA-954p-556p-r752
github.com/koxudaxi/datamodel-code-generator/commit/5fdba4a09f2d7a9996a504975b7ef7d63e3715bb
github.com/koxudaxi/datamodel-code-generator/releases/tag/0.61.0
github.com/advisories/GHSA-954p-556p-r752
github.com/CVEProject/cvelistV5/tree/main/cves/2026/54xxx/CVE-2026-54690.json
nvd.nist.gov/vuln/detail/CVE-2026-54690
github.com/koxudaxi/datamodel-code-generator
pypi.org/project/datamodel-code-generator
Left out here: 84 versions and the rest of 3 source descriptions. The JSON record has them.