# `datamodel-code-generator` vulnerable to code execution on import via unescaped `validators` entries in --extra-template-data

Unescaped validators entries in datamodel-code-generator's --extra-template-data are interpolated into a Pydantic @field_validator decorator, executing arbitrary code when the generated module is imported.

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

**Target:** Python code generator CLI (--extra-template-data, Pydantic v2 output)
**Root cause:** _process_validators interpolates field names and validator mode into the Jinja template wrapped in unescaped single quotes, with no repr(), identifier check or quote-escaping; Import.from_full_path similarly emits function_path verbatim into an import line.
**Steps:**
1. Craft an --extra-template-data JSON with a model entry containing a validators array
2. Set a field name or mode containing a single quote to break out of the string literal, e.g. injecting an arbitrary positional expression into `@field_validator(...)`
3. Alternatively place a `;` in the `function` path so it lands in the generated `from <prefix> import <suffix>` line
4. Run datamodel-code-generator with Pydantic v2 output to generate the module
5. Import the generated module; the injected expression/statement executes at class-definition time
**How found:** Code review of the _process_validators sink and its Jinja template, noticing f-string interpolation of fields/mode into single-quoted decorator arguments without repr() or escaping, plus the secondary Import.from_full_path sink.
**Exploitation:** Attacker supplies a malicious --extra-template-data file (e.g. via PR to a project-local *.template-data.json consumed by make codegen or a pre-commit hook, or a config snippet from a README/issue). When the victim generates and imports the module, the injected Python expression runs in the developer's interpreter or CI runner.
**Escalation:** Same threat model as GHSA-wjv6-jcfj-mf9r but escalates from docstring leak to silent RCE; multi-tenant CI where one tenant's config is read by another tenant's build widens blast radius.
**Insight:** Code generators that emit Python from config data are a code-injection surface: grep templates for interpolated values inside quotes and for import-path builders that split on '.', since a stray quote or ';' in config becomes executable at import time.

