Files
vuln-osv/data/PyPI/GHSA-8m8r-38jm-f355.json

1 line
5.6 KiB
JSON
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
{"schema_version":"1.9.0","id":"GHSA-8m8r-38jm-f355","published":"2026-07-28T21:44:09Z","modified":"2026-08-04T14:40:45.155617320Z","aliases":["CVE-2026-54656","PYSEC-2026-3559"],"summary":"`datamodel-code-generator` vulnerable to code execution on import via unescaped `validators` entries in --extra-template-data","details":"### Summary\n\nWhen 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.\n\n### Details\n\nSink: `src/datamodel_code_generator/model/pydantic_v2/base_model.py`, `_process_validators` (lines 405–449, at tag `0.60.1` / commit `a321547e`):\n\n```python\ndef _process_validators(self) -> None:\n validators = self.extra_template_data.get(\"validators\")\n if not validators:\n return\n ...\n for validator in validators:\n fields = validator.get(\"fields\") or [validator.get(\"field\")]\n fields = [f for f in fields if f]\n if not fields:\n continue\n function_path: str = validator[\"function\"]\n function_name = function_path.rsplit(\".\", 1)[-1]\n mode = validator.get(\"mode\", \"after\")\n fields_str = \", \".join(f\"'{f}'\" for f in fields) # (A) UNESCAPED\n ...\n mode_str = f\"mode='{mode}'\" # (B) UNESCAPED\n prepared_validators.append({\n \"fields_str\": fields_str,\n \"mode_str\": mode_str,\n \"method_name\": method_name,\n \"function_name\": function_name,\n \"mode\": mode,\n })\n self._additional_imports.append(Import.from_full_path(function_path)) # (C)\n```\n\nThe strings from (A) and (B) flow verbatim into `src/datamodel_code_generator/model/template/pydantic_v2/BaseModel.jinja2`:\n\n```jinja\n@field_validator({{ v.fields_str }}, {{ v.mode_str }})\n```\n\nThere is no `repr()` call, no identifier check, and no quote-escaping.\n\nSecondary 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.\n\n### PoC\n\nA self-contained one-file PoC is available here: https://gist.github.com/thegr1ffyn/34d5c647e74487ffb2be27c76dace2aa\n\n### Impact\n\nArbitrary 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:\n\n- Pull requests adding or modifying project-local `*.template-data.json` / `.codegen.json` files consumed by a `make codegen` rule or pre-commit hook.\n- Configuration snippets pasted from issue templates, READMEs, or third-party guides.\n- Multi-tenant CI systems where one tenant's config file is read by another tenant's build.\n\nSame blast radius as GHSA-wjv6-jcfj-mf9r, but silent RCE rather than a docstring leak — significantly higher impact under the same threat model.\n\n\n \n> Introduced in 0.52.1 by commit [`a2b27562`](https://github.com/koxudaxi/datamodel-code-generator/commit/a2b27562) (*Add --validators option for Pydantic v2 field validators*).\n\n### Resolution\n\nThe 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.\n\n### Remediation\n\nUpgrade to `datamodel-code-generator` `0.60.2` or later.\n\nThis issue affects `datamodel-code-generator` versions `>= 0.52.1, <= 0.60.1` and is fixed in `0.60.2`.\n\nSubmitted by: Hamza Haroon (thegr1ffyn)","affected":[{"package":{"name":"datamodel-code-generator","ecosystem":"PyPI","purl":"pkg:pypi/datamodel-code-generator"},"ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0.52.1"},{"fixed":"0.60.2"}]}],"versions":["0.52.1","0.52.2","0.53.0","0.54.0","0.54.1","0.55.0","0.56.0","0.56.1","0.57.0","0.58.0","0.59.0","0.59.1","0.60.0","0.60.1"],"database_specific":{"last_known_affected_version_range":"<= 0.60.1","source":"https://github.com/github/advisory-database/blob/main/advisories/github-reviewed/2026/07/GHSA-8m8r-38jm-f355/GHSA-8m8r-38jm-f355.json"}}],"references":[{"type":"WEB","url":"https://github.com/koxudaxi/datamodel-code-generator/security/advisories/GHSA-8m8r-38jm-f355"},{"type":"WEB","url":"https://github.com/koxudaxi/datamodel-code-generator/commit/a43d02906111a2fdcaf13ee5b62eb2da85376f19"},{"type":"PACKAGE","url":"https://github.com/koxudaxi/datamodel-code-generator"},{"type":"WEB","url":"https://github.com/koxudaxi/datamodel-code-generator/releases/tag/0.60.2"}],"database_specific":{"cwe_ids":["CWE-94"],"github_reviewed":true,"github_reviewed_at":"2026-07-28T21:44:09Z","nvd_published_at":null,"severity":"HIGH"},"severity":[{"type":"CVSS_V3","score":"CVSS:3.1/AV:L/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H"}]}