Code injection is a vulnerability in which an application assembles part of its own program text from untrusted input, so that the input executes as instructions in the language the application is written in. MITRE catalogs the weakness as CWE-94, Improper Control of Generation of Code, where the failure is that characters capable of altering the syntax of the resulting code reach it without being neutralized.
Dependency injection shares the word and nothing else, being a design pattern for handing a component its collaborators, with no untrusted input anywhere in it. What separates the genuine injection classes from one another is which interpreter receives the attacker's syntax, and the recipient here is the application's own runtime.
What Has to Be True for the Flaw to Exist
An application cannot run attacker-supplied instructions unless it holds a construct that converts text into executable code while the program is running. MITRE scopes the weakness accordingly, listing it against interpreted languages as a class and marking it as only sometimes prevalent even there.
MITRE records that dependency in the taxonomy by giving the weakness a second parent. Besides sitting in the general injection family, code injection is filed under CWE-913, Improper Control of Dynamically-Managed Code Resources, which covers a program's failure to control what can be read out of, or written into, the variables, classes, functions, and executable statements it manages while running.
Where the Evaluation Constructs Hide
The obvious case is an eval call or its equivalent, and MITRE separates that case as CWE-95, which it also names eval injection. Searching a codebase for those function names finds the instances a developer would have recognized anyway.
Review tends to walk past the other two children of CWE-94, where the evaluation is harder to see than a function call.
- Static code injection, CWE-96, where the input is inserted into an executable resource, which MITRE describes as a library, a configuration file, or a template. Injection and execution are separated in time and sometimes by a deployment step, so neither half looks dangerous in isolation.
- Template engine injection, CWE-1336, is better known as server-side template injection, where input reaches a template before the engine processes it. MITRE's own assessment is that an attacker in that position can invoke arbitrary expressions.
Two neighbors are routinely filed under this weakness and belong elsewhere. Unsafe reflection, CWE-470, where external input selects which class or method to invoke, sits beside code injection under the same dynamic-code parent rather than beneath it. Expression language injection, CWE-917, sits under command injection in MITRE's research view, even though an expression language evaluates inside the application process.
How Code Injection, Command Injection, and SQL Injection Differ
Of the four, only a code injection attack runs inside the process holding the application's own state. Open database connections, decrypted secrets, and the session currently being served are all available to the injected instructions, without any of them being authenticated to a second time. Each of the four appears among the types of web application attacks that recur across assessments.
Where It Ranks Against Its Neighbors
The 2025 CWE Top 25 ranks CWE-94 tenth, on a score of 7.57, with seven of its CVEs recorded in CISA's catalog of exploited vulnerabilities. OS command injection sits directly above it at 7.85 and carries 20, so two weaknesses ranked beside each other differ nearly threefold in confirmed exploitation.
Rank and exploitability are separate measures, and MITRE rates the likelihood of exploit for this weakness as medium. It also rates automated static analysis as highly effective at finding it, which is worth knowing because that rating does not hold for every weakness ranked nearby.
Why Filtering the Input Does Not Work
Input filtering rests on the assumption that the dangerous content can be listed in advance. The payload here is syntax in a general-purpose language, and such a language offers many routes to the same operation, among them string concatenation, character arithmetic, encoding, and resolving a name at runtime in place of writing it out.
Removing the construct is the control that does hold, and the shape it takes follows what the feature actually needs. Where that feature needs structured input, parse it as data with a format that has no execution semantics. A feature that needs a calculation can have an expression evaluator with no access to the host runtime. A name that must be resolved at runtime should be checked against a fixed list of permitted values, not filtered for dangerous characters.
What Injected Code Reaches
MITRE lists four consequences for code injection, and three of them follow from where the code runs. Redirecting control flow is the general case. Where the surrounding code decides authentication, the injection reaches that decision directly. And because the instructions run as the application, they reach resources the attacker has no route to from outside.
The fourth consequence outlasts the incident, since MITRE assigns the weakness a non-repudiation impact on the grounds that what injected control code does frequently goes unrecorded. The application keeps serving traffic while its own logs show an ordinary session.
A logged request and an unlogged action can be the same event seen from two places. Raven Runtime Prevention watches execution rather than requests, so instructions the application did not ship with are stopped at the point they try to run. See it at Runtime Prevention.

