CVE-2026-54656High· 7.8▾ Twilight`datamodel-code-generator` vulnerable to code execution on import via unescaped `validators` entries in --extra-template-data
▾ Twilight zone — High severity, or a signal on a lesser flaw
impact 42.9 · likelihood 0 · exploitation 0
Need a working PoC? Pro members can cast a request and our team develops one — it lands right here.
Exploit-prediction probability, daily snapshots since Jul 29.
Disclosure to exploitation, from the record and what we observed since indexing it.
Disclosed via GHSA
0.1%
0.1% → 0.2%
When the Pydantic v2 output mode is in use, datamodel-code-generator reads a validators array from each model entry in the --extra-template-data file and synthesises a Pydantic @field_validator(...) decorator from each entry. The field names and the validator mode are interpolated into the decorator call wrapped in unescaped single quotes. A value containing ' breaks out of the string literal, letting an attacker emit an arbitrary positional Python expression into the decorator. The expression is evaluated at class-definition time, i.e. the moment the developer imports the generated module. This is the same trust model as the recently-published GHSA-wjv6-jcfj-mf9r (extras-file comment injection) but the impact is full RCE rather than a docstring leak.
Sink: src/datamodel_code_generator/model/pydantic_v2/base_model.py, _process_validators (lines 405–449, at tag 0.60.1 / commit a321547e):
def _process_validators(self) -> None:
validators = self.extra_template_data.get("validators")
if not validators:
return
...
for validator in validators:
fields = validator.get("fields") or [validator.get("field")]
fields = [f for f in fields if f]
if not fields:
continue
function_path: str = validator["function"]
function_name = function_path.rsplit(".", 1)[-1]
mode = validator.get("mode", "after")
fields_str = ", ".join(f"'{f}'" for f in fields) # (A) UNESCAPED
...
mode_str = f"mode='{mode}'" # (B) UNESCAPED
prepared_validators.append({
"fields_str": fields_str,
"mode_str": mode_str,
"method_name": method_name,
"function_name": function_name,
"mode": mode,
})
self._additional_imports.append(Import.from_full_path(function_path)) # (C)
The strings from (A) and (B) flow verbatim into src/datamodel_code_generator/model/template/pydantic_v2/BaseModel.jinja2:
@field_validator({{ v.fields_str }}, {{ v.mode_str }})
There is no repr() call, no identifier check, and no quote-escaping.
Secondary sink at (C): Import.from_full_path(function_path) splits on the last . and emits from <prefix> import <suffix>. A ; in function_path therefore lands in the generated import line and runs as a statement at module load.
A self-contained one-file PoC is available here: https://gist.github.com/thegr1ffyn/34d5c647e74487ffb2be27c76dace2aa
Arbitrary code execution in the developer's interpreter / CI runner the moment the generated module is imported. Anyone who accepts a --extra-template-data file from an untrusted source is impacted:
*.template-data.json / .codegen.json files consumed by a make codegen rule or pre-commit hook.Same blast radius as GHSA-wjv6-jcfj-mf9r, but silent RCE rather than a docstring leak — significantly higher impact under the same threat model.
Introduced in 0.52.1 by commit
a2b27562(Add --validators option for Pydantic v2 field validators).
The fix validates validators entries with Pydantic models before rendering them. Field names must be valid non-keyword Python identifiers, function must be a dotted Python identifier path, and mode must be one of Pydantic's supported validator modes. The generated decorator arguments now render field names with repr() and mode with !r, so validated values are still emitted as Python string literals.
Upgrade to datamodel-code-generator 0.60.2 or later.
This issue affects datamodel-code-generator versions >= 0.52.1, <= 0.60.1 and is fixed in 0.60.2.
Submitted by: Hamza Haroon (thegr1ffyn)
datamodel-code-generator >= 0.52.1, <= 0.60.1Upgrade to a patched release:
datamodel-code-generator 0.60.2Connected by shared product, vendor, weakness, or advisory.
CVE-2026-54653High· 8.8`datamodel-code-generator` vulnerable to code injection in via attacker-controlled `default_factory` schema field
CVE-2026-54654High· 7.8`datamodel-code-generator` vulnerable to code injection via unescaped carriage return in `--extra-template-data` `comment` field
CVE-2026-54655High· 7.8`datamodel-code-generator` vulnerable to code execution on import via `x-python-type` JSON-Schema extension in datamodel-code-generator
CVE-2026-55415High· 7.5datamodel-code-generator vulnerable to code injection via `x-python-import` / `customTypePath` in generated import statements
CVE-2026-54621High· 7.8`datamodel-code-generator` vulnerable to code injection via unescaped carriage return in GraphQL Union description
CVE-2025-14576High· 7.8Insufficient validation of node IDs in Qt SVG module allows arbitrary QML/JavaScript code injection when loading malicious SVG files through the VectorImage component in Qt Quick