CVE-2026-55415
Python vulnerability analysis and mitigation

Overview

CVE-2026-55415 is a code injection vulnerability in datamodel-code-generator, a Python tool that generates Pydantic, dataclass, TypedDict, and msgspec models from OpenAPI, JSON Schema, and other schema formats. A malicious input schema can embed newline characters in the x-python-import or customTypePath schema extensions, causing attacker-controlled Python statements to be injected at module scope in the generated output file, which execute when the generated model is imported. The vulnerability affects versions >= 0.11.6 and <= 0.63.0; it was disclosed privately on June 12, 2026, and published to the GitHub Advisory Database on July 28, 2026. It carries a CVSS v3.1 base score of 7.5 (High) (Github Advisory, Feedly).

Technical details

The root cause is improper neutralization of code directives (CWE-94, CWE-95) in two unsanitized schema-controlled extension paths. The Import.from_full_path() method in src/datamodel_code_generator/imports.py splits the input only on . characters and passes all other characters — including newlines — verbatim to create_line(), which renders the import statement without any identifier validation. Two entry points reach this sink: (1) the x-python-import extension processed in jsonschema.py:get_ref_data_type(), and (2) the customTypePath extension consumed via get_data_type_from_full_path(). By embedding a newline in the name field of x-python-import (e.g., "name": "getcwd\nprint(*open('/etc/passwd'),...)") or in customTypePath, an attacker causes create_line() to emit a legitimate import statement followed by an arbitrary Python statement at module scope. This vulnerability survived the v0.61.0 security release, which hardened sibling sinks (x-python-type, default_factory, GraphQL-union-description, validators) but left x-python-import and customTypePath unguarded. A public PoC is available (Github Advisory).

Impact

Successful exploitation results in arbitrary Python code execution with the privileges of the process that imports the generated model — achieving full confidentiality, integrity, and availability impact. The attack is triggered at model-import time, meaning any developer, CI/CD pipeline, or multi-tenant code-generation service that processes an untrusted schema and subsequently imports the generated module is at risk. The published PoC demonstrates arbitrary file read (exfiltrating /etc/passwd), and the same primitive can be extended to full remote code execution, credential theft, or supply chain compromise if generated models are distributed to downstream consumers (Github Advisory).

Exploitation steps

  1. Craft a malicious schema: Create a JSON Schema or OpenAPI document containing either an x-python-import extension with a newline-embedded name value, or a customTypePath field with a newline-embedded payload. Example (payload_a.json):
{
  "type": "object",
  "title": "Root",
  "required": ["f"],
  "properties": {"f": {"$ref": "#/$defs/Evil"}},
  "$defs": {
    "Evil": {
      "type": "object",
      "x-python-import": {
        "module": "os",
        "name": "getcwd\nprint(*open('/etc/passwd'),file=open('/tmp/loot','w'),sep='',end='')"
      }
    }
  }
}
  1. Deliver the schema to the target: Host the malicious schema at a public URL, submit it to a multi-tenant code-generation service, contribute it to a shared API specification repository, or supply it as a vendor/third-party OpenAPI document.
  2. Trigger code generation: The victim (or an automated pipeline) runs datamodel-codegen --input payload_a.json --input-file-type jsonschema --output model.py. The tool processes the schema without validating the extension values and emits the injected statement verbatim into model.py at module scope.
  3. Trigger code execution: The victim (or tooling) runs python -c "import model" or any equivalent import. The injected Python statement executes immediately with the importing process's privileges, e.g., reading /etc/passwd and writing it to /tmp/loot.
  4. Escalate: Replace the file-read payload with a reverse shell, credential harvester, or supply-chain backdoor — the only constraint is that the payload must not contain a . character (easily satisfied using attribute-free builtins) (Github Advisory).

Indicators of compromise

  • File System: Unexpected files in /tmp/ (e.g., dmcg_xpi_loot, dmcg_ctp_loot) containing sensitive data such as /etc/passwd contents; generated Python model files (model.py or similar) containing bare Python statements (e.g., print(...), exec(...), __import__(...)) outside of import blocks at module scope.
  • Logs: CI/CD pipeline logs showing datamodel-codegen invoked against external or third-party schema URLs followed by unexpected process output or file writes; Python import errors or unexpected stdout/stderr output when importing generated models.
  • Process: Unusual child processes spawned by the Python interpreter during model import (e.g., curl, wget, bash, nc) that are not expected from a model import operation; network connections initiated by the Python process immediately after importing a generated model.
  • Network: Outbound connections from developer workstations or CI runners to unexpected external hosts shortly after schema processing, potentially indicating data exfiltration or reverse shell establishment (Github Advisory).

Mitigation and workarounds

Upgrade datamodel-code-generator to version 0.64.0 or later, which validates x-python-import and customTypePath values as dotted Python identifier paths using _validate_dotted_python_identifier_path before passing them to the import generation code (Release 0.64.0, Fix Commit). As an interim workaround where upgrading is not immediately possible, avoid running datamodel-codegen against untrusted, third-party, or externally sourced schemas, and do not import generated model files without first reviewing them for unexpected statements at module scope. CI/CD pipelines ingesting external API specifications should pin schema sources to known-good, reviewed versions and add a linting step to inspect generated output before import.

Community reactions

The vulnerability was discovered and reported by security researcher Hamza Haroon (thegr1ffyn), with analysis support from mhamzakhattak and Muzammilxi, and was confirmed by the maintainer prior to publication (Github Advisory). The advisory notes this is an incomplete fix relative to the v0.61.0 security release, which hardened several sibling sinks but missed the x-python-import and customTypePath paths — a detail likely to draw attention from the security community given the tool's ~4,000 GitHub stars and broad use in API-driven Python projects. No significant broader media coverage or social media discussion has been identified at time of writing.

Additional resources


SourceThis report was generated using AI

Related Python vulnerabilities:

CVE ID

Severity

Score

Technologies

Component name

CISA KEV exploit

Has fix

Published date

CVE-2026-55415HIGH7.5
  • Python logoPython
  • datamodel-code-generator
NoYesJul 28, 2026
CVE-2026-55391HIGH7.5
  • Python logoPython
  • datamodel-code-generator
NoYesJul 28, 2026
CVE-2026-55390HIGH7.5
  • Python logoPython
  • datamodel-code-generator
NoYesJul 28, 2026
CVE-2026-55389HIGH7.5
  • Python logoPython
  • datamodel-code-generator
NoYesJul 28, 2026
CVE-2026-55403LOW3.7
  • Python logoPython
  • datamodel-code-generator
NoYesJul 28, 2026

Free Vulnerability Assessment

Benchmark your Cloud Security Posture

Evaluate your cloud security practices across 9 security domains to benchmark your risk level and identify gaps in your defenses.

Request assessment

Get a personalized demo

Ready to see Wiz in action?

"Best User Experience I have ever seen, provides full visibility to cloud workloads."
David EstlickCISO
"Wiz provides a single pane of glass to see what is going on in our cloud environments."
Adam FletcherChief Security Officer
"We know that if Wiz identifies something as critical, it actually is."
Greg PoniatowskiHead of Threat and Vulnerability Management