# `datamodel-code-generator` vulnerable to code execution on import via `x-python-type` JSON-Schema extension in datamodel-code-generator

datamodel-code-generator forwards the x-python-type JSON-Schema extension verbatim into generated Python annotations, letting a malicious schema inject a statement that executes when the generated module is imported.

- Payout: Research
- Severity: high
- Program: datamodel-code-generator
- Found by: thegr1ffyn
- Disclosed: 2026-07-28
- CVE: CVE-2026-54655
- Write-up quality: 8/10
- Original: https://github.com/advisories/GHSA-m34r-v34r-rf9q
- Library page: https://bugbountylibrary.com/r/ghsa%3AGHSA-m34r-v34r-rf9q
- Tags: area:oss domain:oss impact:rce kind:research platform:ghsa sev:high tech:python technique:incomplete-fix technique:source-review vuln:rce

**Target:** datamodel-codegen JSON Schema parser and generated model templates
**Root cause:** The x-python-type extension value is used as the generated field annotation with only a dot-rewrite sanitiser that fires only when '.' appears before the first '['; placing '[' early skips it and the raw value lands in the class body.
**Steps:**
1. Craft a JSON Schema field with `x-python-type` set to `X[1]; <payload>` so the prefix before `[` contains no dot and the sanitiser is skipped.
2. Run `datamodel-codegen` with default settings on the schema; the value is emitted verbatim into `{{ field.type_hint }}` in the model template.
3. Generated module contains `from __future__ import annotations`, making `X[1]` a lazy string while the statement after `;` is parsed as a real class-body statement.
4. Import the generated module; the injected statement executes at class-definition time in the developer's interpreter or CI runner.
**How found:** Code review of `_get_python_type_override` in parser/jsonschema.py revealed the single dot-rewrite sanitiser and its condition on the substring before the first `[`, suggesting a bypass by placing `[` early; combined with default `from __future__ import annotations` to keep the subscript lazy.
**Exploitation:** Attacker supplies a valid JSON Schema (e.g. via third-party OpenAPI doc, customer-supplied schema in an SDK-generation platform, or a malicious commit) whose x-python-type carries a `;`-separated payload; the victim runs datamodel-codegen and later imports the generated file, executing arbitrary code silently in their interpreter or CI runner.
**Escalation:** Blast radius extends to CI runners and developer workstations wherever untrusted schemas are ingested; payload stays dormant until the generated file is imported.
**Insight:** When a sanitiser's condition depends on a delimiter position (here '.' before first '['), test inputs that move or introduce the other delimiter earlier to skip the rewrite entirely; also check whether `from __future__ import annotations` turns part of the injected value into a lazy string, leaving the rest as live statements.

