# `datamodel-code-generator` vulnerable to code injection in via attacker-controlled `default_factory` schema field

datamodel-code-generator interpolates attacker-controlled `default_factory` schema values raw into generated Python, executing code when the generated model is imported.

- Payout: Research
- Severity: high
- Program: datamodel-code-generator
- Found by: thegr1ffyn
- Disclosed: 2026-07-28
- CVE: CVE-2026-54653
- Write-up quality: 7/10
- Original: https://github.com/advisories/GHSA-386q-5hp3-95m9
- Library page: https://bugbountylibrary.com/r/ghsa%3AGHSA-386q-5hp3-95m9
- Tags: area:oss domain:oss impact:integrity impact:rce kind:research platform:ghsa sev:high tech:python technique:chained technique:source-review vuln:rce

**Target:** Python code generator (JSON Schema/OpenAPI/Avro/Protobuf/XSD parsers, Pydantic/dataclass/msgspec output)
**Root cause:** Schema `default_factory` values are stored in `extras` and interpolated verbatim as raw Python expressions into `Field(default_factory=...)`/`field(default_factory=...)`, with `repr()` explicitly skipped for that key in dataclass/msgspec sinks.
**Steps:**
1. Craft a JSON Schema property with a `"default_factory"` key whose value is an arbitrary Python expression.
2. Run `datamodel-codegen` with default flags against the schema (e.g. `--input-file-type jsonschema --output-model-type pydantic_v2.BaseModel`).
3. Generated model contains `Field(default_factory=<raw expression>)`.
4. Import the generated module; the expression evaluates at class-definition time, executing attacker code.
**How found:** Code review of the schema-to-extras-to-sink chain: noticed `default_factory` in `DEFAULT_FIELD_KEYS`, traced it through `extras` to sinks where `repr()` is explicitly skipped for that key, then built a PoC matrix across input/output types.
**Exploitation:** Attacker supplies a malicious schema (third-party API spec, registry schema, vendored file, remote URL) to a developer or CI pipeline; the generated Python is imported, executing arbitrary code in the importer's process (PoC copies /etc/passwd to a tmp file; same primitive allows env exfiltration, writes, network calls, CI runner RCE).
**Escalation:** No special flags needed; affects all JSON-Schema-shaped inputs and pydantic_v2/dataclass/msgspec outputs, enabling CI runner compromise.
**Insight:** When auditing code generators, grep for keys explicitly excluded from `repr()`/escaping in template sinks — a special-case skip is a strong signal of raw interpolation; also check whether the key is in default field-key allowlists so no flag is needed.

