Jul 29, 2026·7 min read·2 visits
A Server-Side Request Forgery (SSRF) flaw in datamodel-code-generator allows remote attackers to read sensitive internal network and host configurations (such as cloud instance metadata) by submitting schemas containing malicious remote references.
CVE-2026-54690 (GHSA-954p-556p-r752) is a Server-Side Request Forgery (SSRF) vulnerability in the datamodel-code-generator Python library from version 0.9.1 to 0.61.0. The library silently resolves remote JSON Schema references ($ref) over HTTP/HTTPS without verifying the target hosts or IP addresses. Because it automatically follows redirects and permits requests to local and private networks by default, an attacker can submit a crafted schema to trigger connections to internal subnets, localhost, or cloud metadata endpoints. Retrieved sensitive data is subsequently parsed and reflected in the generated Python model files, resulting in local and private data disclosure.
The component under analysis is datamodel-code-generator, a Python-based utility that automates the generation of Pydantic models, dataclasses, and standard Python types from target formats like JSON Schema and OpenAPI. This tool is often integrated into automated CI/CD pipelines, API gateway generation tools, and developer portals. When users submit schemas containing remote references, the tool attempts to automatically fetch and parse these resources to construct the complete code representation.
This automatic resolution mechanism introduces a significant attack surface if the utility is deployed in a server-side environment processing user-supplied schemas. Because the parser fetches remote schemas via standard HTTP/HTTPS protocols, an attacker can supply custom references targeting internal services rather than public endpoints. The software then acts as a proxy, querying resources that are normally protected by firewalls or network segmentation.
The weakness is classified as a Server-Side Request Forgery (SSRF) vulnerability, registered under CWE-918. When exploited, the vulnerability allows unauthorized actors to perform network reconnaissance, access internal APIs, and extract system environment data. The primary risk occurs when the utility integrates the fetched remote resource directly into the generated Python file, reflecting private information to the client.
The underlying flaw resides in how datamodel-code-generator handles URI references within schema structures. When the parser encounters a $ref key containing an absolute HTTP or HTTPS URL, it invokes the network fetch routine. In vulnerable versions (0.9.1 up to 0.61.0), the application fails to restrict the destination hostname, port, or IP address during this resolution step.
The core of the vulnerability lies within src/datamodel_code_generator/http.py. The execution environment calls the get_body() function, passing the remote URL directly to the HTTP client. By default, the HTTP client (httpx) is configured with the follow_redirects=True directive. This setup allows the client to automatically traverse HTTP redirect chains without executing intermediate validation checks.
Additionally, the default state of the library configured allow_remote_refs to None. While this configuration triggers a console warning indicating that remote references are being processed, it does not stop the execution path. The underlying networking routine proceeds to establish connections to any specified target, including private loopback addresses (such as 127.0.0.1) and cloud provider metadata services (such as 169.254.169.254).
The parsed schema engine attempts to convert the fetched response into a JSON structure or plain text, incorporating the resulting data into the internal AST representation. Because the output generation pipeline writes these values into class properties, comments, or field descriptions, the fetched information is exposed to the user. This design turns a standard parsing operation into an interactive information disclosure channel.
To analyze the vulnerability, we inspect the legacy implementation of get_body in src/datamodel_code_generator/http.py. The vulnerable function accepts a raw string URL and resolves it immediately via httpx.get without any validation layer:
# Vulnerable legacy implementation
def get_body(
url: str,
headers: Sequence[tuple[str, str]] | None = None,
ignore_tls: bool = False,
query_parameters: Sequence[tuple[str, str]] | None = None,
timeout: float = DEFAULT_HTTP_TIMEOUT,
) -> str:
httpx = _get_httpx()
try:
# The client automatically follows redirects to arbitrary hosts
response = httpx.get(
url,
headers=headers,
verify=not ignore_tls,
follow_redirects=True,
params=query_parameters,
timeout=timeout,
)
except Exception as e:
msg = f"Failed to fetch {url}: {e}"
raise SchemaFetchError(msg) from eThe patch introduced in version 0.61.0 implements a defense mechanism that forces manual redirection verification and validates each IP address resolved from the target host. It disables automatic redirects (follow_redirects=False) and iteratively checks each redirect hop against a strict validation function, _validate_url_for_fetch().
# Patched secure implementation
def _validate_url_for_fetch(url: str, *, allow_private_network: bool) -> None:
parsed_url = urlparse(url)
if parsed_url.scheme not in ("http", "https"):
raise SchemaFetchError("Unsupported scheme")
hostname = parsed_url.hostname
if not hostname:
raise SchemaFetchError("Missing host")
if allow_private_network:
return
# Check for localhost names and resolve hostname
host = hostname.rstrip(".").lower()
if host in _UNSAFE_HOST_NAMES or host.endswith(".localhost"):
raise SchemaFetchError("Blocked host")
# Resolve IP addresses and verify they are globally routable
ips = _get_ips_from_host(host)
for ip in ips:
if not ip.is_global:
raise SchemaFetchError("Resolved IP is not public")By ensuring that every IP address resolves to a globally routable destination, the updated code successfully neutralizes access to RFC 1918 private subnets and local loopback adapters. The validation is performed before any TCP connection is established, preventing connection-state side-channel attacks.
An attacker can exploit this vulnerability by submitting a schema that contains a remote reference pointing to an internal resource. If the target application processes this schema automatically, the underlying library initiates an outbound request to the specified target. The attacker does not need network level access to the internal network; they rely on the parsing server to bridge the boundary.
The exploit payload is embedded directly within a JSON Schema structure under a key like properties or definitions. For example, setting the $ref parameter to http://169.254.169.254/latest/meta-data/iam/security-credentials/ forces the parser to request AWS temporary credentials. The metadata service responds with a plaintext JSON string containing the access keys.
Upon receiving the response, the library attempts to interpret the credentials as a schema fragment. While the credentials will not parse as a valid JSON Schema, the library's error handling or partial string deserialization often formats the response into the output representation. In many cases, the raw returned content is written as default field values or docstrings within the final generated .py file, which is then served back to the attacker.
The primary security consequence of this vulnerability is the complete compromise of the application's underlying cloud or local environment context. By targeting cloud metadata services, attackers can acquire transient authentication tokens, allowing them to assume the IAM role assigned to the host server. This access enables remote actors to read private datastores, modify cloud infrastructure, or escalate privileges within the target tenant.
In containerized or bare-metal environments, the vulnerability allows actors to perform intranet port scanning and host discovery. By submitting schemas pointing to internal IP addresses (such as 10.0.0.0/8 or 192.168.0.0/16) and measuring connection latency or analyzing error messages, attackers can map out the backend network topology. This provides a critical stepping stone for further lateral movement within the corporate environment.
The CVSS v3.1 score of 8.2 reflects a high confidentiality impact. Because the vulnerability changes the scope of authorization (Scope: Changed), the impact propagates from the application context to the underlying infrastructure provider. No specific privileges are required to submit the schema, and the attack complexity is minimal once a parsing endpoint is exposed.
The recommended remediation path is to upgrade datamodel-code-generator to version 0.61.0 or higher. This release changes the default execution behavior to block connections targeting non-public IP ranges. If upgrading immediately is not feasible, security engineers should implement strict configuration parameters when programmatically invoking the code generator.
Specifically, the allow_private_network parameter must be explicitly configured as False. When using the command-line interface, operators must omit the --allow-private-network flag, which is disabled by default in patched versions. To eliminate all network risks, teams can set the --no-allow-remote-refs parameter, forcing the parser to resolve references solely from local filesystems.
# Recommended secure programmatic invocation
from datamodel_code_generator import generate
generate(
input_path="user_schema.json",
allow_remote_refs=False, # Restricts fetching from the network entirely
allow_private_network=False, # Block local IP ranges if remote refs are needed
output=Path("models.py"),
)Additionally, defense-in-depth measures should be established at the network and system levels. Applications running the parser should be containerized and isolated using firewall policies or Kubernetes NetworkPolicies that deny all egress traffic to internal IP ranges. Cloud metadata services should be hardened by enforcing IMDSv2 with a hop limit of 1, preventing containerized applications from querying the host-level metadata endpoint.
CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:H/I:L/A:N| Attribute | Detail |
|---|---|
| CWE ID | CWE-918 |
| Attack Vector | Network |
| CVSS Base Score | 8.2 (High) |
| Exploit Status | PoC Available |
| Affected Versions | >= 0.9.1, < 0.61.0 |
| Mitigation Option | Upgrade to 0.61.0 or disable remote references |
CVE-2026-54666 identifies a high-severity code injection vulnerability in the swagger-typescript-api code generator library. The library fails to sanitize route paths parsed from OpenAPI Specification (OAS) documents before interpolating them into generated TypeScript and JavaScript client code. When a developer processes a compromised or malicious OpenAPI specification file, the library writes unescaped string literals and dynamic execution blocks directly into backtick template literals. When the generated client's corresponding API method is executed, the embedded JavaScript executes dynamically with the privileges of the active process.
A type confusion vulnerability exists in the optimizing JIT compilation pipeline of Mozilla SpiderMonkey (Firefox) prior to version 151.0.3. An error in the JIT compiler's Range Analysis optimization pass allows the unsafe elimination of critical type guards. Under specific execution flows, an unauthenticated remote attacker can trigger a mismatch between predicted compile-time types and actual runtime types, resulting in memory corruption and arbitrary code execution within the browser's sandbox environment.
CVE-2026-54656 is a high-severity arbitrary code execution vulnerability in the koxudaxi/datamodel-code-generator Python package. When processing validator metadata from external configuration files passed via the --extra-template-data argument, the code generator performs unescaped string interpolation into Pydantic v2 @field_validator decorators. This allows local attackers to construct malicious configuration files that inject arbitrary Python statements into generated models, executing code upon downstream import. This vulnerability has been resolved in version 0.60.2.
CVE-2026-55391 is a server-side request forgery (SSRF) bypass vulnerability in the datamodel-code-generator package. The vulnerability occurs due to a Time-of-Check to Time-of-Use (TOCTOU) race condition during DNS resolution, combined with a failure to inspect embedded IPv4-in-IPv6 address mappings. By deploying a malicious DNS server with a low Time-To-Live (TTL) configuration, an attacker can bypass private address blocklists and coerce the application to connect to internal services or local endpoints.
A critical code injection vulnerability exists in datamodel-code-generator from version 0.17.0 up to 0.60.1. The vulnerability allows remote attackers who supply a malicious JSON schema to execute arbitrary Python code. This occurs when the schema specifies a payload inside the 'default_factory' field extra, which is rendered directly into generated code without sanitization. When downstream processes load or import the output code, the evaluation of the class definition immediately triggers the execution of the injected code.
An arbitrary local file read and path traversal bypass vulnerability in datamodel-code-generator before version 0.62.0 allows unauthenticated remote attackers to read arbitrary files via crafted JSON-Schema $ref references using the file:// scheme or directory traversal sequences.