Summary
datamodel-code-generator fails to safely handle GraphQL Union description text when rendering Python models, allowing attacker-controlled schema content to escape from generated comments into live code.
If a malicious or compromised GraphQL schema is used as input, the generated Python models can contain injected code that executes automatically when the module is imported.
datamodel-code-generator fails to safely handle GraphQL Union description text when rendering Python models, allowing attacker-controlled schema content to escape from generated comments into live code.
If a malicious or compromised GraphQL schema is used as input, the generated Python models can contain injected code that executes automatically when the module is imported.
Affected context
This vulnerability occurs when datamodel-code-generator is used to generate Python models from GraphQL schemas that include Union types.
Specifically, Union description fields are inserted into Python # comments in the Jinja2 templates without sanitizing newline or carriage return characters.
Environments that ingest schemas from untrusted, third-party, or multi-tenant sources are most exposed, as schema authors may influence the generated Python code.
This vulnerability occurs when datamodel-code-generator is used to generate Python models from GraphQL schemas that include Union types.
Specifically, Union description fields are inserted into Python # comments in the Jinja2 templates without sanitizing newline or carriage return characters.
Environments that ingest schemas from untrusted, third-party, or multi-tenant sources are most exposed, as schema authors may influence the generated Python code.
Exploit preconditions
- Attack surface: GraphQL schema input consumed by datamodel-code-generator, particularly Union type descriptions.
- Required access: Ability to supply or modify the GraphQL schema used as input to the generator (e.g., via configuration, API, repository, or schema registry).
- Trigger point: Running datamodel-code-generator to produce Python models, followed by importing the generated module in any Python runtime.
- Why exploitation is possible: Description values are treated as plain text comments, but embedded newline/carriage return sequences break out of the
#comment context, allowing arbitrary Python statements to be inserted and later executed.
- Attack surface: GraphQL schema input consumed by datamodel-code-generator, particularly Union type descriptions.
- Required access: Ability to supply or modify the GraphQL schema used as input to the generator (e.g., via configuration, API, repository, or schema registry).
- Trigger point: Running datamodel-code-generator to produce Python models, followed by importing the generated module in any Python runtime.
- Why exploitation is possible: Description values are treated as plain text comments, but embedded newline/carriage return sequences break out of the
#comment context, allowing arbitrary Python statements to be inserted and later executed.
Why this happens
The core issue is improper neutralization of control characters when embedding untrusted text into source-code comments.
In the affected templates, GraphQL Union descriptions are rendered into Python as # comments with no escaping or filtering of newline and carriage return characters.
This allows an attacker to terminate the comment and introduce new lines containing executable Python code.
Conceptually, this aligns with CWE-94: Improper Control of Generation of Code ('Code Injection') and relates to CWE-1336: Improper Neutralization of Special Elements Used in a Template Engine, as the Jinja2 templates propagate untrusted content directly into generated source.
The core issue is improper neutralization of control characters when embedding untrusted text into source-code comments.
In the affected templates, GraphQL Union descriptions are rendered into Python as # comments with no escaping or filtering of newline and carriage return characters.
This allows an attacker to terminate the comment and introduce new lines containing executable Python code.
Conceptually, this aligns with CWE-94: Improper Control of Generation of Code ('Code Injection') and relates to CWE-1336: Improper Neutralization of Special Elements Used in a Template Engine, as the Jinja2 templates propagate untrusted content directly into generated source.
Potential impact
- Execution of arbitrary Python code when the generated models are imported.
- Compromise of the application using the generated models, including data exfiltration or tampering.
- Installation of backdoors or further malware via the build or code-generation pipeline.
- Lateral movement within CI/CD or developer environments that run the generator and import the models.
- Execution of arbitrary Python code when the generated models are imported.
- Compromise of the application using the generated models, including data exfiltration or tampering.
- Installation of backdoors or further malware via the build or code-generation pipeline.
- Lateral movement within CI/CD or developer environments that run the generator and import the models.
General mitigation guidance
Mitigation typically focuses on hardening code generation boundaries and treating schema content as untrusted input:
- Sanitize or escape newline, carriage return, and other control characters before embedding schema descriptions into code templates.
- Use templating constructs that automatically escape user-controlled content or limit what can be interpolated into generated source files.
- Restrict or validate schema sources, avoiding blind trust in externally supplied or multi-tenant GraphQL schemas.
- Run code generation and subsequent imports under least privilege, separating build-time and runtime trust boundaries to reduce blast radius.
Mitigation typically focuses on hardening code generation boundaries and treating schema content as untrusted input:
- Sanitize or escape newline, carriage return, and other control characters before embedding schema descriptions into code templates.
- Use templating constructs that automatically escape user-controlled content or limit what can be interpolated into generated source files.
- Restrict or validate schema sources, avoiding blind trust in externally supplied or multi-tenant GraphQL schemas.
- Run code generation and subsequent imports under least privilege, separating build-time and runtime trust boundaries to reduce blast radius.
How teams detect issues like this
Detection approaches can combine code review, static analysis, and pipeline checks:
- Review templates for direct insertion of untrusted data into generated code without escaping, especially in comments and string literals.
- Apply static analysis or linters to generated code to flag suspicious constructs, such as unexpected statements adjacent to comments derived from schema descriptions.
- Implement CI/CD policies that treat generated code as untrusted until scanned, including checks for schema-driven code injection patterns.
- Use automated template-security review tools where available to detect improper neutralization of special elements in templating systems.
Detection approaches can combine code review, static analysis, and pipeline checks:
- Review templates for direct insertion of untrusted data into generated code without escaping, especially in comments and string literals.
- Apply static analysis or linters to generated code to flag suspicious constructs, such as unexpected statements adjacent to comments derived from schema descriptions.
- Implement CI/CD policies that treat generated code as untrusted until scanned, including checks for schema-driven code injection patterns.
- Use automated template-security review tools where available to detect improper neutralization of special elements in templating systems.

