Skip to main content
CVE Vulnerability Database
Vulnerability Database/CVE-2026-54654

CVE-2026-54654: datamodel-code-generator RCE Vulnerability

CVE-2026-54654 is a remote code execution vulnerability in datamodel-code-generator that allows attackers to inject malicious Python code through comment fields. This article covers technical details, affected versions, and patches.

Published:

CVE-2026-54654 Overview

CVE-2026-54654 is a code injection vulnerability [CWE-94] affecting datamodel-code-generator, a Python tool that generates data models from schema definitions. Versions from 0.14.1 through 0.60.1 fail to neutralize carriage returns and newline characters in the --extra-template-data comment field. An attacker who controls the comment value can inject arbitrary Python code into generated model files. The injected code executes when the generated module is imported by a downstream application. The issue is fixed in version 0.60.2.

Critical Impact

Attacker-controlled comment values are rendered directly into Python # comments across six Jinja2 templates, enabling arbitrary code execution in any process that imports the generated model.

Affected Products

  • datamodel-code-generator versions 0.14.1 through 0.60.1
  • Generated modules using TypeAliasAnnotation.jinja2, TypedDict.jinja2, dataclass.jinja2, msgspec.Struct.jinja2
  • Generated modules using pydantic/BaseModel.jinja2 and pydantic_v2/BaseModel.jinja2

Discovery Timeline

  • 2026-07-28 - CVE-2026-54654 published to NVD
  • 2026-07-29 - Last updated in NVD database
  • Fixed release - datamodel-code-generator 0.60.2 published on GitHub

Technical Details for CVE-2026-54654

Vulnerability Analysis

The vulnerability stems from improper neutralization of control characters when rendering user-supplied comment data into Jinja2 templates. The --extra-template-data option accepts a JSON structure containing a comment field. That field is written verbatim into a Python # comment inside six built-in templates. Because a # comment in Python terminates at the first newline, a carriage return or line-feed character in the comment value ends the comment and begins a new line of executable Python source. Any code following the injected newline runs when the generated module is imported.

Root Cause

The original sanitizer normalized line endings but did not prevent multi-line comment values from escaping the # comment context. Templates rendered the value with no per-line # prefix, so newlines produced raw Python statements. The classification maps to Improper Control of Generation of Code [CWE-94].

Attack Vector

Exploitation requires an attacker to supply the value of extra_template_data.comment, either through a build pipeline, a configuration file consumed by datamodel-code-generator, or a schema-processing service that forwards user input into the generator. Local user interaction is required to run the generator and later import the emitted module. Successful exploitation yields code execution with the privileges of the importing process.

python
     return value.replace("\r\n", "\n").replace("\r", "\n")
 
 
+def inline_comment_safe(value: str | None) -> str | None:
+    """Make a value safe for a generated inline Python comment."""
+    if value is None:
+        return None
+    safe_value = comment_safe(value) or ""
+    return safe_value.replace("\v", "\n").replace("\f", "\n").replace("\n", "\n# ")
+
+
+def _safe_extra_template_data(extra_template_data: dict[str, Any]) -> dict[str, Any]:
+    if not isinstance(comment := extra_template_data.get("comment"), str):
+        return extra_template_data
+    return {**extra_template_data, "comment": inline_comment_safe(comment)}
+
+
 class _RenderedDataModelField:
     """Proxy a field with a pre-rendered docstring for built-in templates."""

Source: GitHub commit b73abb5. The patch introduces inline_comment_safe, which converts vertical tab, form feed, and newline characters to \n# so that each subsequent line remains inside a Python comment. _safe_extra_template_data applies the sanitizer to the comment key before templates render.

Detection Methods for CVE-2026-54654

Indicators of Compromise

  • Generated Python model files containing multi-line comments where subsequent lines begin without a # prefix.
  • Presence of executable statements such as import, os.system, or subprocess calls in files produced by datamodel-code-generator.
  • Build logs referencing --extra-template-data values sourced from untrusted schemas, configuration files, or upstream services.

Detection Strategies

  • Scan repositories and build artifacts for datamodel-code-generator versions between 0.14.1 and 0.60.1 in requirements.txt, pyproject.toml, and lockfiles.
  • Statically analyze generated model files for unexpected top-level statements outside of class or type definitions.
  • Diff generated modules across CI runs to identify newly introduced code that does not correspond to schema fields.

Monitoring Recommendations

  • Alert on invocations of datamodel-codegen where the --extra-template-data argument references files or environment variables containing user input.
  • Track child-process creation and outbound network activity from Python interpreters that import freshly generated model modules.
  • Log and review CI/CD pipeline changes that modify template data passed to code generators.

How to Mitigate CVE-2026-54654

Immediate Actions Required

  • Upgrade datamodel-code-generator to version 0.60.2 in every build environment and container image.
  • Audit existing generated Python modules for injected statements before importing them in production.
  • Treat any schema, JSON configuration, or CLI argument that feeds extra_template_data.comment as untrusted input.

Patch Information

The fix ships in datamodel-code-generator 0.60.2. See the GitHub Release 0.60.2 and the GHSA-wjv6-jcfj-mf9r advisory for full details. The patch adds inline_comment_safe and applies it via _safe_extra_template_data before Jinja2 rendering.

Workarounds

  • Remove the comment key from any --extra-template-data payload until the upgrade is applied.
  • Pre-sanitize comment values by stripping \r, \n, \v, and \f characters before passing them to the generator.
  • Isolate code generation in a sandboxed CI stage and require manual review of generated modules before they are imported by downstream services.
bash
# Upgrade to the patched release
pip install --upgrade 'datamodel-code-generator>=0.60.2'

# Verify installed version
python -c "import datamodel_code_generator; print(datamodel_code_generator.__version__)"

Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

Default Legacy - Prefooter | Experience the World’s Most Advanced Cybersecurity Platform

Experience the Most Advanced Cybersecurity Platform

See how the world’s most intelligent, autonomous cybersecurity platform can protect your organization today and into the future.