CWE-94: Improper Control of Generation of Code ('Code Injection')

What is CWE-94?

The product uses externally influenced input to construct part or all of a code segment without properly neutralizing syntax or other elements that can change the intended code's behavior.

Data statistics

OWASP TOP 10:2025 RANK5 — A05:2025 — Injection
RELATED CVES (365 DAYS)871
ABSTRACTIONBase
LIKELIHOOD OF EXPLOITMedium

Vulnerabilities mapped to CWE-94

871 vulnerabilities273.8% increase year over year

Vulnerabilities in CISA KEV for CWE-94

11 vulnerabilities37.5% increase year over year

Official definition

ByMitre CWE

The product constructs all or part of a code segment using externally-influenced input from an upstream component, but it does not neutralize or incorrectly neutralizes special elements that could modify the syntax or behavior of the intended code segment.

Detailed description

This weakness occurs when data from an upstream component is incorporated into dynamically generated code and remains able to influence its syntax, control flow, or executable operations. The resulting code may perform actions beyond the product's intended behavior, particularly when input reaches an evaluation or execution mechanism without strict restrictions on permitted constructs. The record identifies implementation as the phase in which this weakness is realized and lists interpreted languages and AI/ML technologies as applicable contexts, with platform prevalence recorded as sometimes or undetermined.

Characteristics

This is a base-level, simple weakness involving an externally influenced value flowing into generated code. Its defining behavior is the failure to constrain or correctly neutralize special syntax, allowing input to alter intended control flow or invoke operations that were not meant to be available. The record also identifies the related term "Code Injection" and associates the weakness with interpreted environments and AI/ML applications.

Common consequences

Possible consequences include bypassing authentication or another protection mechanism when injected code controls access decisions, gaining privileges or assuming another identity, and executing unauthorized code or commands. The latter can affect confidentiality, integrity, and availability, including arbitrary code execution and loss of data integrity. Injected actions may also be unlogged, allowing activity to be hidden and weakening non-repudiation.

ImpactScopeExplanation
Bypass Protection MechanismAccess ControlIn some cases, injectable code controls authentication; this may lead to a remote vulnerability.
Gain Privileges or Assume IdentityAccess ControlInjected code can access resources that the attacker is directly prevented from accessing.
Execute Unauthorized Code or CommandsIntegrity, Confidentiality, AvailabilityWhen a product allows a user's input to contain code syntax, it might be possible for an attacker to craft the code in such a way that it will alter the intended control flow of the product. As a result, code injection can often result in the execution of arbitrary code. Code injection attacks can also lead to loss of data integrity in nearly all cases, since the control-plane data injected is always incidental to data recall or writing.
Hide ActivitiesNon-RepudiationOften the actions performed by injected control code are unlogged.

Risk mitigations

Architecture and design: Refactor the product so it does not need to generate code dynamically. If dynamic generation cannot be avoided, run the code in a strictly bounded jail or sandbox, such as an environment using chroot or AppArmor; this only limits impact on the operating system, may not be feasible, and must not introduce jail-related weaknesses such as CWE-243.

Implementation: Treat all input as malicious and apply strict allowlist validation that accepts only values conforming to the required length, type, range, syntax, consistency, and business rules. Do not rely only on denylists or searches for malformed input. Limit permitted code constructs, since checking that a value is alphanumeric may still allow references to dangerous functions such as system, exec, or exit. For Python, the record notes ast.literal_eval as an alternative to eval because it is designed not to execute code, but marks this practice as discouraged because deeply nested input can still cause excessive memory or stack consumption.

Testing and operation: Use fuzzing, robustness testing, and fault injection with diverse inputs, checking that the product does not become unstable, crash, or produce incorrect results. Use an environment with automatic taint propagation that prevents command execution with tainted variables, such as Perl's -T switch, while carefully validating data before it is treated as untainted. The same taint-based control is listed under both compilation or build hardening and environment hardening.

  1. Refactoring · Architecture and DesignRefactor your program so that you do not have to dynamically generate code.
  2. Architecture and DesignRun your code in a "jail" or similar sandbox environment that enforces strict boundaries between the process and the operating system. This may effectively restrict which code can be executed by your product. Examples include the Unix chroot jail and AppArmor. In general, managed code may provide some protection. This may not be a feasible solution, and it only limits the impact to the operating system; the rest of your application may still be subject to compromise. Be careful to avoid CWE-243 and other weaknesses related to jails.
  3. Input Validation · ImplementationAssume all input is malicious. Use an "accept known good" input validation strategy, i.e., use a list of acceptable inputs that strictly conform to specifications. Reject any input that does not strictly conform to specifications, or transform it into something that does. When performing input validation, consider all potentially relevant properties, including length, type of input, the full range of acceptable values, missing or extra inputs, syntax, consistency across related fields, and conformance to business rules. As an example of business rule logic, "boat" may be syntactically valid because it only contains alphanumeric characters, but it is not valid if the input is only expected to contain colors such as "red" or "blue." Do not rely exclusively on looking for malicious or malformed inputs. This is likely to miss at least one undesirable input, especially if the code's environment changes. This can give attackers enough room to bypass the intended validation. However, denylists can be useful for detecting potential attacks or determining which inputs are so malformed that they should be rejected outright. To reduce the likelihood of code injection, use stringent allowlists that limit which constructs are allowed. If you are dynamically constructing code that invokes a function, then verifying that the input is alphanumeric might be insufficient. An attacker might still be able to reference a dangerous function that you did not intend to allow, such as system(), exec(), or exit().
  4. TestingUse dynamic tools and techniques that interact with the product using large test suites with many diverse inputs, such as fuzz testing (fuzzing), robustness testing, and fault injection. The product's operation may slow down, but it should not become unstable, crash, or generate incorrect results.
  5. Compilation or Build Hardening · OperationRun the code in an environment that performs automatic taint propagation and prevents any command execution that uses tainted variables, such as Perl's "-T" switch. This will force the program to perform validation steps that remove the taint, although you must be careful to correctly validate your inputs so that you do not accidentally mark dangerous inputs as untainted (see CWE-183 and CWE-184).
  6. Environment Hardening · OperationRun the code in an environment that performs automatic taint propagation and prevents any command execution that uses tainted variables, such as Perl's "-T" switch. This will force the program to perform validation steps that remove the taint, although you must be careful to correctly validate your inputs so that you do not accidentally mark dangerous inputs as untainted (see CWE-183 and CWE-184).
  7. Implementation · Effectiveness: Discouraged Common PracticeFor Python programs, it is frequently encouraged to use the ast.literal_eval() function instead of eval, since it is intentionally designed to avoid executing code. However, an adversary could still cause excessive memory or stack consumption via deeply nested structures [REF-1372], so the python documentation discourages use of ast.literal_eval() on untrusted data [REF-1373].

Detection methods

Automated static analysis, commonly implemented as SAST, can detect some instances without executing the product. It can model data flow and control flow and look for paths from input sources to sinks where data reaches external components or lower layers such as the operating system. Its coverage is limited to patterns that the analysis can model, so it does not establish that every instance has been found.

MethodApproachEffectiveness
Automated Static AnalysisAutomated static analysis, commonly referred to as Static Application Security Testing (SAST), can find some instances of this weakness by analyzing source code (or binary/compiled code) without having to execute it. Typically, this is done by building a model of data flow and control flow, then searching for potentially-vulnerable patterns that connect "sources" (origins of input) with "sinks" (destinations where the data interacts with external components, a lower layer such as the OS, etc.)High

Representative vulnerabilities

The official record provides representative examples, not an exhaustive list. Examples include LLM and AI application frameworks that pass user input or a provider-crafted response into Python exec or eval, including CVE-2023-29374, CVE-2024-5565, and CVE-2024-4181. Other examples involve Python, PHP, and Perl evaluation or direct code injection, such as CVE-2022-2054, CVE-2008-5071, CVE-2002-1750, CVE-2008-5305, CVE-2002-1752, CVE-2002-1753, CVE-2005-1527, CVE-2005-2837, CVE-2005-1921, CVE-2005-2498, CVE-2005-3302, CVE-2007-1253, CVE-2001-1471, CVE-2002-0495, CVE-2005-1876, CVE-2005-1894, and CVE-2003-0395. The set also includes CVE-2021-22204, where an upstream string-boundary issue enabled evaluation injection, and CVE-2020-8218, described as code injection in a VPN product; both are noted as exploited in the wild in the supplied record.

Below are representative vulnerabilities related to this CWE, prioritized by severity.

Sources (4)

CWE™ Program, operated by The MITRE Corporation. Copyright © 2006–2026, The MITRE Corporation. The MITRE Corporation hereby grants you a non-exclusive, royalty-free license to use CWE for research, development, and commercial purposes. CWE Terms of Use.

Learn more

Run an in-depth assessment with complete web risk management

CyStack VulnScan continuously discovers assets, validates vulnerabilities, and helps security teams prioritize remediation across the organization.

Explore CyStack VulnScan