CVE-2026-55389 Overview
CVE-2026-55389 is a path traversal vulnerability [CWE-22] in datamodel-code-generator, a Python tool that generates Pydantic v2 models, dataclasses, TypedDict, and msgspec.Struct from OpenAPI, JSON Schema, GraphQL, Avro, Protobuf, and raw JSON, YAML, or CSV inputs. Versions prior to 0.62.0 resolve JSON Schema $ref targets in src/datamodel_code_generator/parser/jsonschema.py through is_url and _get_ref_body without containing file:// or ../ traversal references to the input directory. The tool also fails to honor the --no-allow-remote-refs flag for these references, allowing arbitrary local file reads. Version 0.62.0 fixes the issue.
Critical Impact
A malicious JSON Schema input can read arbitrary local files from the host running datamodel-code-generator, exposing source code, credentials, and configuration data.
Affected Products
- datamodel-code-generator versions prior to 0.62.0
- Build pipelines, CI/CD systems, and developer workstations that process untrusted OpenAPI or JSON Schema inputs
- Automated code generation services accepting user-supplied schemas
Discovery Timeline
- 2026-07-28 - CVE-2026-55389 published to NVD
- 2026-07-29 - Last updated in NVD database
Technical Details for CVE-2026-55389
Vulnerability Analysis
The flaw lives in the JSON Schema reference resolver at src/datamodel_code_generator/parser/jsonschema.py. When datamodel-code-generator encounters a $ref in a schema, it delegates resolution to _get_ref_body, which invokes is_url to determine whether the target is remote. The pre-0.62.0 logic treats any file:// URI as a legitimate local reference and bypasses the --no-allow-remote-refs guard. It also does not verify that the resolved path stays inside the input directory, so ../ traversal segments escape the intended root.
An attacker who supplies a schema containing {"$ref": "file:///etc/passwd"} or {"$ref": "../../../etc/shadow"} causes the parser to read that file and embed its contents into generation output or trigger side effects observable through generated artifacts and errors.
Root Cause
The root cause is missing containment logic in _get_ref_body. The function conflates URL fetching with local filesystem access and short-circuits the allow_remote_refs check whenever the scheme is file://. Path normalization against the input directory is absent, so relative traversal succeeds.
Attack Vector
Exploitation requires the victim to run datamodel-code-generator against an attacker-controlled schema. This is common in CI/CD pipelines that generate client SDKs from third-party OpenAPI documents. No authentication or user interaction beyond normal tool invocation is required.
def _get_ref_body(self, resolved_ref: str) -> dict[str, YamlValue]:
"""Get the body of a reference from URL or remote file."""
if is_url(resolved_ref):
- if not resolved_ref.startswith("file://") and self.http_local_ref_path is None:
+ url_scheme = urlparse(resolved_ref).scheme
+ uses_local_http_path = url_scheme in {"http", "https"} and self.http_local_ref_path is not None
+ if not uses_local_http_path:
if self.allow_remote_refs is False:
msg = (
f"Fetching remote $ref is disabled: {resolved_ref}\n"
- "Reason: --no-allow-remote-refs was set, so HTTP(S) $ref targets are not fetched.\n"
+ "Reason: --no-allow-remote-refs was set, so external $ref targets are not fetched.\n"
"If this schema and all of its remote references are trusted, pass --allow-remote-refs. "
"If a trusted remote reference points to an internal schema registry, also pass "
"--allow-private-network."
)
raise Error(msg)
- if self.allow_remote_refs is None:
+ if self.allow_remote_refs is None and url_scheme in {"http", "https"}:
warn_deprecated(
"behavior.remote-ref-default",
Source: GitHub Commit 2ff4a72. The patch reroutes the scheme check through urlparse, restricts the local-HTTP shortcut to http/https schemes, and forces file:// references through the standard allow_remote_refs gate.
Detection Methods for CVE-2026-55389
Indicators of Compromise
- JSON Schema or OpenAPI documents containing $ref values that begin with file:// or include ../ traversal sequences
- Generated model files that unexpectedly contain contents of system files such as /etc/passwd, .env, or private keys
- CI/CD job logs showing datamodel-code-generator accessing files outside the schema input directory
Detection Strategies
- Inventory installed datamodel-code-generator versions across developer workstations and build agents; flag any version below 0.62.0.
- Statically scan schema inputs for $ref values containing file://, absolute filesystem paths, or .. segments before generation runs.
- Review generated output artifacts in code review for unexpected embedded content that indicates local file exfiltration.
Monitoring Recommendations
- Monitor build agents for open() or read() operations by the Python interpreter against paths outside the designated schema directory during generation.
- Alert on outbound egress from CI runners when generation output is transmitted to external systems, since read data may be exfiltrated downstream.
- Track dependency manifests (requirements.txt, pyproject.toml, poetry.lock) for pinned versions of datamodel-code-generator below 0.62.0.
How to Mitigate CVE-2026-55389
Immediate Actions Required
- Upgrade datamodel-code-generator to version 0.62.0 or later across all environments.
- Treat all third-party OpenAPI and JSON Schema documents as untrusted input and validate them before running the generator.
- Run code generation inside isolated containers with read-only mounts limited to the schema directory.
Patch Information
The fix is available in datamodel-code-generator 0.62.0. Details are published in GitHub Security Advisory GHSA-8359-h9fx-j6v9 and shipped in the 0.62.0 release. The corrective commit is 2ff4a72.
Workarounds
- Preprocess input schemas to strip or reject any $ref value beginning with file:// or containing .. segments.
- Execute datamodel-code-generator inside a sandbox or container with no access to sensitive host paths.
- Always pass --no-allow-remote-refs and inline all trusted references locally under a restricted directory prior to invocation.
# Upgrade to the patched release
pip install --upgrade 'datamodel-code-generator>=0.62.0'
# Verify installed version
datamodel-codegen --version
# Run generation in an isolated container with a read-only schema mount
docker run --rm \
--read-only \
-v "$(pwd)/schemas:/schemas:ro" \
-v "$(pwd)/out:/out" \
python:3.12-slim \
sh -c 'pip install datamodel-code-generator==0.62.0 && \
datamodel-codegen --no-allow-remote-refs \
--input /schemas/api.yaml \
--output /out/models.py'
Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

