Skip to main content

datamodel-code-generator EUVDEUVD-2026-50069

| CVE-2026-54691 HIGH
Server-Side Request Forgery (SSRF) (CWE-918)
2026-07-28 https://github.com/koxudaxi/datamodel-code-generator GHSA-rfr2-mq9m-x2qx
8.2
CVSS 3.1 · Vendor: https://github.com/koxudaxi/datamodel-code-generator
Share

Severity by source

Vendor (https://github.com/koxudaxi/datamodel-code-generator) PRIMARY
8.2 HIGH
AV:N/AC:L/PR:N/UI:R/S:C/C:H/I:L/A:N
vuln.today AI
6.9 MEDIUM

AC:H because exploitation requires the optional [http] extra plus attacker control of the URL/redirect and reachable internal services; UI:R and S:C retained, C:H from metadata/credential disclosure, I:L from reflected schema content.

3.1 AV:N/AC:H/PR:N/UI:R/S:C/C:H/I:L/A:N
4.0 AV:N/AC:H/AT:N/PR:N/UI:P/VC:H/VI:L/VA:N/SC:L/SI:L/SA:N

Primary rating from Vendor (https://github.com/koxudaxi/datamodel-code-generator).

CVSS VectorVendor: https://github.com/koxudaxi/datamodel-code-generator

Attack Vector
Network
Attack Complexity
Low
Privileges Required
None
User Interaction
Required
Scope
Changed
Confidentiality
High
Integrity
Low
Availability
None

Lifecycle Timeline

3
Source Code Evidence Fetched
Jul 28, 2026 - 21:50 vuln.today
Analysis Generated
Jul 28, 2026 - 21:50 vuln.today
CVE Published
Jul 28, 2026 - 21:30 github-advisory
HIGH 8.2

DescriptionCVE.org

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):

python
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/18de777d6c800a3b47715425e3f3e8f5

Impact

Who is impacted. Anyone who runs datamodel-codegen with a --url they didn't fully verify, or who runs it inside a network with reachable internal services. Realistic scenarios:

  1. Trojan documentation / README. A blog post or README example reads datamodel-codegen --url https://schemas.example.com/user.json -o user.py. The attacker controls example.com, redirects to http://169.254.169.254/latest/meta-data/iam/security-credentials/<role>, and the IAM credentials end up as a docstring in user.py.
  2. Internal port scan / disclosure. Iterating --url http://127.0.0.1:<port>/health probes localhost services; non-HTML, non-error responses confirm a service and leak its body into the generated file.
  3. CI poisoning. A PR adds a Makefile rule that calls datamodel-codegen --url $(SCHEMA_URL); the CI runner reaches every internal service in its VPC and the response lands in PR artifacts.

Suggested fix. Resolve the URL host, reject loopback / private / link-local / multicast / reserved IPs by default, disable redirects by default (follow_redirects=False), re-validate after each redirect if the user opts into following them, and add an --allow-private-network flag for opt-in legitimate use.

Maintainer resolution

This report was fixed together with GHSA-954p-556p-r752 by the private security PR koxudaxi/datamodel-code-generator-ghsa-rfr2-mq9m-x2qx#1, 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.

The patch hardens the shared HTTP fetcher used by both direct CLI --url fetching and remote JSON Schema/OpenAPI $ref resolution:

  • validates HTTP(S) URLs before fetching;
  • blocks localhost, loopback, private, link-local, reserved, and other non-public network targets by default;
  • disables automatic redirect following and validates each redirect target before requesting it;
  • adds --allow-private-network / allow_private_network=True as an explicit opt-in 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)

AnalysisAI

Server-side request forgery in the datamodel-code-generator Python package (versions >= 0.9.1 and <= 0.60.2) allows an attacker who controls or influences a --url schema source to make the codegen host fetch arbitrary internal addresses - loopback, RFC1918, link-local 169.254.169.254 cloud metadata, and unique-local IPv6 - and have the response body reflected into the generated .py file as schema titles, property names, and Field(description=...) strings. The issue only affects installations that include the optional [http] extra; the fetcher applies no allow-list or IP/host validation and follows redirects unconditionally, with text/html rejection as its only filter, so non-HTML JSON/YAML endpoints (IAM credential metadata, internal admin APIs) pass through and leak into artifacts commonly committed to repositories or surfaced in CI output. Publicly available exploit code exists (a self-contained one-file PoC), but the flaw is not confirmed actively exploited (not in CISA KEV); EPSS is low at 0.21% (11th percentile), and the assessed vector (CVSS:3.1/AV:N/AC:H/PR:N/UI:R/S:C/C:H/I:L/A:N, 8.2) reflects high confidentiality impact tempered by required victim interaction and AC:H.

Technical ContextAI

The root cause is CWE-918 (Server-Side Request Forgery) in src/datamodel_code_generator/http.py, function get_body (lines 31-61 at tag 0.60.1 / commit a321547e), which calls httpx.get(url, ..., follow_redirects=True) against any URL supplied via the CLI --url argument (or reached through a redirect chain) with no allow-list, deny-list, or IP/host validation. The only defensive filter is rejection of responses whose content-type contains text/html; every other content type - JSON, YAML, plain text from internal APIs and cloud metadata services - is returned as the response text. That text is then used by parser/base.py:1326 (_get_text_from_url) as the input schema, so attacker-chosen data becomes class attributes, docstrings, and Field(description=...) values in the emitted Python source. Two properties compound the risk: follow_redirects=True lets a public, attacker-controlled URL 302 the fetch to an internal target, and the absence of private/link-local IP filtering means the same code path reaches 169.254.169.254 IMDS, localhost admin services, or VPC-internal endpoints when the codegen process runs on a cloud instance or CI runner. The Python packaging ecosystem is the relevant supply-chain surface (CPE pkg:pip/datamodel-code-generator); only users who installed the [http] extra (pip install 'datamodel-code-generator[http]') are exposed, since the core install has no HTTP fetcher.

RemediationAI

Upgrade to the patched release: vendor-released patch 0.61.0 fixes this issue (with GHSA-954p-556p-r752) and hardens the shared HTTP fetcher used by both direct CLI --url fetching and remote JSON Schema/OpenAPI $ref resolution - it validates HTTP(S) URLs before fetching, blocks localhost, loopback, private, link-local, reserved, and other non-public targets by default, disables automatic redirect following, re-validates each redirect target before requesting it, and adds an explicit --allow-private-network / allow_private_network=True opt-in for trusted internal schema endpoints (installing pip install 'datamodel-code-generator[http]>=0.61.0' is sufficient). Because remote $ref fetching remains governed by --allow-remote-refs and non-public targets additionally require --allow-private-network, avoid enabling --allow-private-network in CI or shared build environments, since that reinstates the original SSRF exposure for any attacker-influenced URL. If upgrade is not immediately possible, stop invoking datamodel-codegen --url against URLs from untrusted sources such as blog posts, README examples, or PR-supplied Makefile variables, point --url only at schema hosts you control and verify the response chain does not redirect, or remove the datamodel-code-generator[http] extra so the fetcher is unavailable (trade-off: remote schema and remote $ref support is lost entirely); additionally block egress to 169.254.169.254 and RFC1918 ranges from codegen hosts and CI runners (trade-off: legitimate internal schema endpoints also become unreachable) and, on cloud instances requiring IMDS, enforce IMDSv2 with hop-limit 1 to reduce credential theft even if a fetch succeeds. Confirm the applied fix via the vendor commit https://github.com/koxudaxi/datamodel-code-generator/commit/5fdba4a09f2d7a9996a504975b7ef7d63e3715bb and the advisory at https://github.com/koxudaxi/datamodel-code-generator/security/advisories/GHSA-rfr2-mq9m-x2qx.

More in Python

View all
CVE-2025-24016 CRITICAL POC
9.9 Feb 10

Wazuh SIEM platform versions 4.4.0 through 4.9.0 contain an unsafe deserialization vulnerability in the DistributedAPI t

CVE-2025-27520 CRITICAL POC
9.8 Apr 04

BentoML version 1.4.2 and earlier contains an unauthenticated remote code execution vulnerability through insecure deser

CVE-2025-2945 CRITICAL POC
9.9 Apr 03

pgAdmin 4 contains critical remote code execution vulnerabilities in the Query Tool download and Cloud Deployment endpoi

CVE-2013-5093 MEDIUM POC
6.8 Sep 27

The renderLocalView function in render/views.py in graphite-web in Graphite 0.9.5 through 0.9.10 uses the pickle Python

CVE-2025-32375 CRITICAL POC
9.8 Apr 09

BentoML is a Python library for building online serving systems optimized for AI apps and model inference. Rated critica

CVE-2014-0224 HIGH POC
7.4 Jun 05

OpenSSL before 0.9.8za, 1.0.0 before 1.0.0m, and 1.0.1 before 1.0.1h does not properly restrict processing of ChangeCiph

CVE-2024-21644 HIGH POC
7.5 Jan 08

pyLoad download manager version prior to 0.5.0b3.dev77 exposes the Flask SECRET_KEY through an unauthenticated endpoint.

CVE-2026-33017 CRITICAL POC
9.3 Mar 17

Langflow (a visual LLM pipeline builder) contains a critical unauthenticated code execution vulnerability (CVE-2026-3301

CVE-2017-9462 HIGH POC
8.8 Jun 06

In Mercurial before 4.1.3, "hg serve --stdio" allows remote authenticated users to launch the Python debugger, and conse

CVE-2026-49869 CRITICAL POC
10.0 Jun 26

Unauthenticated remote code execution affects Kestra OSS (the open-source event-driven orchestration platform) prior to

CVE-2026-39987 CRITICAL POC
9.3 Apr 08

Unauthenticated remote code execution in Marimo ≤0.20.4 allows attackers to execute arbitrary system commands via the `/

CVE-2024-21645 MEDIUM POC
5.3 Jan 08

pyLoad is the free and open-source Download Manager written in pure Python. Rated medium severity (CVSS 5.3), this vulne

Share

EUVD-2026-50069 vulnerability details – vuln.today

This site uses cookies essential for authentication and security. No tracking or analytics cookies are used. Privacy Policy