{"id":"CVE-2026-54690","aliases":["EUVD-2026-50074","GHSA-954p-556p-r752","PYSEC-2026-3560"],"status":"published","title":"datamodel-code-generator vulnerable to SSRF via JSON-Schema `$ref` to HTTP URL (silent by default)","description":"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.","severity":{"version":"3.1","score":8.2,"vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:H/I:L/A:N","level":"high","assessor":"cna","from":"cve"},"epss":{"day":"2026-11-12","score":0.00388,"percentile":0.3341,"model":"v2026.06.15"},"facts":{"in_kev":false,"known_exploited":false,"public_exploit":false,"fix_available":true},"cwes":["CWE-918"],"published":"2026-07-28T21:42:06Z","modified":"2026-10-28T02:31:04Z","fixes":[{"ecosystem":"PyPI","package":"datamodel-code-generator","fixed_in":["0.61.0"],"sources":["ghsa","osv"]}],"affected":[{"source":"ghsa","ecosystem":"PyPI","package":"datamodel-code-generator","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0.9.1"},{"last_affected":"0.60.2"},{"fixed":"0.61.0"}]}]},{"source":"osv","ecosystem":"PyPI","package":"datamodel-code-generator","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0.9.1"},{"fixed":"0.61.0"}]}],"versions":["0.10.0","0.10.1","0.10.2","0.10.3","0.11.0","0.11.1","0.11.10","0.11.11","0.11.12","0.11.13","0.11.14","0.11.15","0.11.16","0.11.17","0.11.18","0.11.19","0.11.2","0.11.20","0.11.3","0.11.4","0.11.5","0.11.6","0.11.7","0.11.8","0.11.9","0.12.0","0.12.1","0.12.2","0.12.3","0.13.0","0.13.1","0.13.2","0.13.3","0.13.4","0.13.5","0.14.0","0.14.1","0.15.0","0.16.0","0.16.1","0.17.0","0.17.1","0.17.2","0.18.0","0.18.1","0.19.0","0.20.0","0.21.0","0.21.1","0.21.2","0.21.3","0.21.4","0.21.5","0.22.0","0.22.1","0.23.0","0.24.0","0.24.1","0.24.2","0.25.0","0.25.1","0.25.2","0.25.3","0.25.4","0.25.5","0.25.6","0.25.7","0.25.8","0.25.9","0.26.0","0.26.1","0.26.2","0.26.3","0.26.4","0.26.5","0.27.0","0.27.1","0.27.2","0.27.3","0.28.0","0.28.1","0.28.2","0.28.3","0.28.4","0.28.5","0.29.0","0.30.0","0.30.1","0.30.2","0.31.0","0.31.1","0.31.2","0.32.0","0.33.0","0.34.0","0.35.0","0.36.0","0.37.0","0.38.0","0.39.0","0.40.0","0.41.0","0.42.0","0.42.1","0.42.2","0.43.0","0.43.1","0.44.0","0.45.0","0.46.0","0.47.0","0.48.0","0.49.0","0.50.0","0.51.0","0.52.0","0.52.1","0.52.2","0.53.0","0.54.0","0.54.1","0.55.0","0.56.0","0.56.1","0.57.0","0.58.0","0.59.0","0.59.1","0.60.0","0.60.1","0.60.2","0.9.1","0.9.2","0.9.3","0.9.4"]},{"source":"osv","ecosystem":"PyPI","package":"datamodel-code-generator","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0.9.1"},{"fixed":"0.61.0"}]}],"versions":["0.10.0","0.10.1","0.10.2","0.10.3","0.11.0","0.11.1","0.11.10","0.11.11","0.11.12","0.11.13","0.11.14","0.11.15","0.11.16","0.11.17","0.11.18","0.11.19","0.11.2","0.11.20","0.11.3","0.11.4","0.11.5","0.11.6","0.11.7","0.11.8","0.11.9","0.12.0","0.12.1","0.12.2","0.12.3","0.13.0","0.13.1","0.13.2","0.13.3","0.13.4","0.13.5","0.14.0","0.14.1","0.15.0","0.16.0","0.16.1","0.17.0","0.17.1","0.17.2","0.18.0","0.18.1","0.19.0","0.20.0","0.21.0","0.21.1","0.21.2","0.21.3","0.21.4","0.21.5","0.22.0","0.22.1","0.23.0","0.24.0","0.24.1","0.24.2","0.25.0","0.25.1","0.25.2","0.25.3","0.25.4","0.25.5","0.25.6","0.25.7","0.25.8","0.25.9","0.26.0","0.26.1","0.26.2","0.26.3","0.26.4","0.26.5","0.27.0","0.27.1","0.27.2","0.27.3","0.28.0","0.28.1","0.28.2","0.28.3","0.28.4","0.28.5","0.29.0","0.30.0","0.30.1","0.30.2","0.31.0","0.31.1","0.31.2","0.32.0","0.33.0","0.34.0","0.35.0","0.36.0","0.37.0","0.38.0","0.39.0","0.40.0","0.41.0","0.42.0","0.42.1","0.42.2","0.43.0","0.43.1","0.44.0","0.45.0","0.46.0","0.47.0","0.48.0","0.49.0","0.50.0","0.51.0","0.52.0","0.52.1","0.52.2","0.53.0","0.54.0","0.54.1","0.55.0","0.56.0","0.56.1","0.57.0","0.58.0","0.59.0","0.59.1","0.60.0","0.60.1","0.60.2","0.9.1","0.9.2","0.9.3","0.9.4"]}],"products":[{"vendor":"koxudaxi","product":"datamodel-code-generator"}],"references":[{"url":"https://github.com/koxudaxi/datamodel-code-generator/security/advisories/GHSA-954p-556p-r752","tags":["x_refsource_CONFIRM","exploit","Exploit","Vendor Advisory","advisory","web"]},{"url":"https://github.com/koxudaxi/datamodel-code-generator/commit/5fdba4a09f2d7a9996a504975b7ef7d63e3715bb","tags":["x_refsource_MISC","Patch","fix","web"]},{"url":"https://github.com/koxudaxi/datamodel-code-generator/releases/tag/0.61.0","tags":["x_refsource_MISC","Release Notes","web"]},{"url":"https://github.com/advisories/GHSA-954p-556p-r752","tags":["advisory"]},{"url":"https://github.com/CVEProject/cvelistV5/tree/main/cves/2026/54xxx/CVE-2026-54690.json","tags":["advisory"]},{"url":"https://nvd.nist.gov/vuln/detail/CVE-2026-54690","tags":["advisory"]},{"url":"https://github.com/koxudaxi/datamodel-code-generator","tags":["package"]},{"url":"https://pypi.org/project/datamodel-code-generator","tags":["package"]}],"sources":{"cve":[{"id":"CVE-2026-54690","title":"datamodel-code-generator vulnerable to SSRF via JSON-Schema `$ref` to HTTP URL (silent by default)","description":"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.","status":"published","published":"2026-07-28T21:42:06.802Z","modified":"2026-07-29T15:24:16.907Z","cvss":[{"version":"3.1","score":8.2,"vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:H/I:L/A:N","level":"high","assessor":"cna"}],"cwes":["CWE-918"],"updated_at":"2026-11-02T13:37:58.613221Z"}],"euvd":[{"id":"EUVD-2026-50074","description":"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.","status":"published","published":"2026-07-28T21:42:06Z","modified":"2026-07-29T15:24:16Z","cvss":[{"version":"3.1","score":8.2,"vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:H/I:L/A:N","level":"high"}],"updated_at":"2026-11-02T18:02:29.807737Z"}],"ghsa":[{"id":"GHSA-954p-556p-r752","title":"datamodel-code-generator vulnerable to SSRF via JSON-Schema `$ref` to HTTP URL (silent by default)","description":"### Summary\n\nJSON-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.\n\n### Details\n\nSink: `src/datamodel_code_generator/parser/jsonschema.py`, `_get_ref_body` (lines 4776–4793, at tag `0.60.1` / commit `a321547e`):\n\n```python\ndef _get_ref_body(self, resolved_ref: str) -\u003e dict[str, YamlValue]:\n    if is_url(resolved_ref):\n        if not resolved_ref.startswith(\"file://\") and self.http_local_ref_path is None:\n            if self.allow_remote_refs is False:\n                raise Error(f\"Fetching remote $ref is disabled: {resolved_ref}...\")\n            if self.allow_remote_refs is None:\n                warn_deprecated(                            # (A) warn only\n                    \"behavior.remote-ref-default\",\n                    details=f\"Reference: {resolved_ref}\",\n                    stacklevel=2,\n                )\n        return self._get_ref_body_from_url(resolved_ref)    # (B) fetch fires\n    return self._get_ref_body_from_remote(resolved_ref)\n```\n\n- (A) emits a deprecation warning when `allow_remote_refs` is its default (`None`); execution falls through to (B).\n- (B) routes the URL through `_get_text_from_url` → `get_body`, the same fetcher described in other report — no IP validation, redirects followed.\n\nThe 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.\n\nOnly affects users who installed the `[http]` extra (`pip install 'datamodel-code-generator[http]'`).\n\n### PoC\n\nA self-contained one-file PoC is available here: https://gist.github.com/thegr1ffyn/562a6972d7dc3f2869458ae93fc608c0\n\n### Impact\n\n**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:\n\n1. **Trojaned OpenAPI document.** A public REST API publishes `openapi.yaml`. One `$ref` points at `http://169.254.169.254/latest/meta-data/iam/security-credentials/\u003crole\u003e`; running `datamodel-codegen` against the spec from an EC2 instance leaks the IAM credentials into the generated client.\n2. **Customer-supplied JSON Schema.** A B2B SaaS auto-generates client code from customer-uploaded schemas. The customer adds an HTTP `$ref` to `http://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.\n3. **CI on a private network.** A PR adds `schemas/inbound.json` with an HTTP `$ref` pointed at a service reachable only from the CI cluster's VPC; the CI runner fetches it and the generated `.py` leaks the response in PR artifacts.\n\nHigher 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.\n\n**Suggested fix.**\n\n1. Flip the default in `parser/base.py`: `allow_remote_refs: bool = False`, and remove the silent-fetch-with-warning fallback at `parser/jsonschema.py:4786-4791`.\n2. When fetching is allowed, apply the same IP/host validation proposed for other submitted SSRF report to both the initial `$ref` URL and every redirect target.\n3. Document HTTP `$ref` in a third-party schema as equivalent to running `curl` on the developer's host.\n\n### Maintainer resolution\n\nThis `$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.\n\nNo 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.\n\nThe 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`.\n\nSubmitted by: Hamza Haroon (thegr1ffyn)","status":"published","published":"2026-07-28T21:42:22Z","modified":"2026-07-28T21:42:24Z","cvss":[{"version":"3.1","score":8.2,"vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:H/I:L/A:N","level":"high"}],"cwes":["CWE-918"],"updated_at":"2026-11-02T14:40:53.707378Z"}],"nvd":[{"id":"CVE-2026-54690","description":"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.","status":"published","published":"2026-07-28T22:17:40.65Z","modified":"2026-10-23T23:10:00.157Z","cvss":[{"version":"3.1","score":8.2,"vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:H/I:L/A:N","level":"high","assessor":"secondary"}],"cwes":["CWE-918"],"updated_at":"2026-11-02T14:12:33.629616Z"}],"osv":[{"id":"CVE-2026-54690","title":"datamodel-code-generator vulnerable to SSRF via JSON-Schema `$ref` to HTTP URL (silent by default)","description":"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.","status":"published","published":"2026-07-28T21:42:06.802Z","modified":"2026-10-28T02:31:04.484794445Z","cvss":[{"version":"3.1","score":8.2,"vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:H/I:L/A:N","level":"high"}],"cwes":["CWE-918"],"updated_at":"2026-11-02T15:45:10.818486Z"},{"id":"GHSA-954p-556p-r752","title":"datamodel-code-generator vulnerable to SSRF via JSON-Schema `$ref` to HTTP URL (silent by default)","description":"### Summary\n\nJSON-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.\n\n### Details\n\nSink: `src/datamodel_code_generator/parser/jsonschema.py`, `_get_ref_body` (lines 4776–4793, at tag `0.60.1` / commit `a321547e`):\n\n```python\ndef _get_ref_body(self, resolved_ref: str) -\u003e dict[str, YamlValue]:\n    if is_url(resolved_ref):\n        if not resolved_ref.startswith(\"file://\") and self.http_local_ref_path is None:\n            if self.allow_remote_refs is False:\n                raise Error(f\"Fetching remote $ref is disabled: {resolved_ref}...\")\n            if self.allow_remote_refs is None:\n                warn_deprecated(                            # (A) warn only\n                    \"behavior.remote-ref-default\",\n                    details=f\"Reference: {resolved_ref}\",\n                    stacklevel=2,\n                )\n        return self._get_ref_body_from_url(resolved_ref)    # (B) fetch fires\n    return self._get_ref_body_from_remote(resolved_ref)\n```\n\n- (A) emits a deprecation warning when `allow_remote_refs` is its default (`None`); execution falls through to (B).\n- (B) routes the URL through `_get_text_from_url` → `get_body`, the same fetcher described in other report — no IP validation, redirects followed.\n\nThe 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.\n\nOnly affects users who installed the `[http]` extra (`pip install 'datamodel-code-generator[http]'`).\n\n### PoC\n\nA self-contained one-file PoC is available here: https://gist.github.com/thegr1ffyn/562a6972d7dc3f2869458ae93fc608c0\n\n### Impact\n\n**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:\n\n1. **Trojaned OpenAPI document.** A public REST API publishes `openapi.yaml`. One `$ref` points at `http://169.254.169.254/latest/meta-data/iam/security-credentials/\u003crole\u003e`; running `datamodel-codegen` against the spec from an EC2 instance leaks the IAM credentials into the generated client.\n2. **Customer-supplied JSON Schema.** A B2B SaaS auto-generates client code from customer-uploaded schemas. The customer adds an HTTP `$ref` to `http://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.\n3. **CI on a private network.** A PR adds `schemas/inbound.json` with an HTTP `$ref` pointed at a service reachable only from the CI cluster's VPC; the CI runner fetches it and the generated `.py` leaks the response in PR artifacts.\n\nHigher 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.\n\n**Suggested fix.**\n\n1. Flip the default in `parser/base.py`: `allow_remote_refs: bool = False`, and remove the silent-fetch-with-warning fallback at `parser/jsonschema.py:4786-4791`.\n2. When fetching is allowed, apply the same IP/host validation proposed for other submitted SSRF report to both the initial `$ref` URL and every redirect target.\n3. Document HTTP `$ref` in a third-party schema as equivalent to running `curl` on the developer's host.\n\n### Maintainer resolution\n\nThis `$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.\n\nNo 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.\n\nThe 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`.\n\nSubmitted by: Hamza Haroon (thegr1ffyn)","status":"published","published":"2026-07-28T21:42:22Z","modified":"2026-09-10T03:51:11.259728609Z","cvss":[{"version":"3.1","score":8.2,"vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:H/I:L/A:N","level":"high"}],"cwes":["CWE-918"],"updated_at":"2026-11-02T15:46:43.123867Z"},{"id":"PYSEC-2026-3560","title":"datamodel-code-generator vulnerable to SSRF via JSON-Schema `$ref` to HTTP URL (silent by default)","description":"### Summary\n\nJSON-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.\n\n### Details\n\nSink: `src/datamodel_code_generator/parser/jsonschema.py`, `_get_ref_body` (lines 4776–4793, at tag `0.60.1` / commit `a321547e`):\n\n```python\ndef _get_ref_body(self, resolved_ref: str) -\u003e dict[str, YamlValue]:\n    if is_url(resolved_ref):\n        if not resolved_ref.startswith(\"file://\") and self.http_local_ref_path is None:\n            if self.allow_remote_refs is False:\n                raise Error(f\"Fetching remote $ref is disabled: {resolved_ref}...\")\n            if self.allow_remote_refs is None:\n                warn_deprecated(                            # (A) warn only\n                    \"behavior.remote-ref-default\",\n                    details=f\"Reference: {resolved_ref}\",\n                    stacklevel=2,\n                )\n        return self._get_ref_body_from_url(resolved_ref)    # (B) fetch fires\n    return self._get_ref_body_from_remote(resolved_ref)\n```\n\n- (A) emits a deprecation warning when `allow_remote_refs` is its default (`None`); execution falls through to (B).\n- (B) routes the URL through `_get_text_from_url` → `get_body`, the same fetcher described in other report — no IP validation, redirects followed.\n\nThe 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.\n\nOnly affects users who installed the `[http]` extra (`pip install 'datamodel-code-generator[http]'`).\n\n### PoC\n\nA self-contained one-file PoC is available here: https://gist.github.com/thegr1ffyn/562a6972d7dc3f2869458ae93fc608c0\n\n### Impact\n\n**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:\n\n1. **Trojaned OpenAPI document.** A public REST API publishes `openapi.yaml`. One `$ref` points at `http://169.254.169.254/latest/meta-data/iam/security-credentials/\u003crole\u003e`; running `datamodel-codegen` against the spec from an EC2 instance leaks the IAM credentials into the generated client.\n2. **Customer-supplied JSON Schema.** A B2B SaaS auto-generates client code from customer-uploaded schemas. The customer adds an HTTP `$ref` to `http://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.\n3. **CI on a private network.** A PR adds `schemas/inbound.json` with an HTTP `$ref` pointed at a service reachable only from the CI cluster's VPC; the CI runner fetches it and the generated `.py` leaks the response in PR artifacts.\n\nHigher 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.\n\n**Suggested fix.**\n\n1. Flip the default in `parser/base.py`: `allow_remote_refs: bool = False`, and remove the silent-fetch-with-warning fallback at `parser/jsonschema.py:4786-4791`.\n2. When fetching is allowed, apply the same IP/host validation proposed for other submitted SSRF report to both the initial `$ref` URL and every redirect target.\n3. Document HTTP `$ref` in a third-party schema as equivalent to running `curl` on the developer's host.\n\n### Maintainer resolution\n\nThis `$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.\n\nNo 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.\n\nThe 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`.\n\nSubmitted by: Hamza Haroon (thegr1ffyn)","status":"published","published":"2026-08-04T11:34:44.428988Z","modified":"2026-08-04T14:30:14.937394684Z","cvss":[{"version":"3.1","score":8.2,"vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:H/I:L/A:N","level":"high"}],"updated_at":"2026-11-02T15:52:56.847083Z"}]}}
