Code injection is a vulnerability in which an application treats attacker-controlled input as executable code in an interpreter, runtime, template engine, or dynamic evaluation feature. It usually arises when untrusted data reaches a dangerous execution sink without a safe separation between data and code.
Successful injection can provide the capabilities of the affected language and process, potentially leading to remote code execution, data theft, account takeover, service disruption, or lateral movement. Input validation helps, but the primary defense is to avoid dynamic execution and use APIs that preserve the distinction between instructions and data.
Code injection vs other injection attacks
| Type | What interprets the input | Example impact |
|---|---|---|
| Code injection | Application language or dynamic evaluator | Attacker-supplied code runs inside the application context |
| OS command injection | Operating-system shell or command processor | Host commands run with the application's privileges |
| SQL injection | Database query engine | Queries are altered to read or change data |
| Cross-site scripting (XSS) | Victim's web browser | Injected script runs in the site's browser origin |
| Server-side template injection | Template engine | Template expressions expose data or reach code execution |
| Expression-language injection | Framework expression evaluator | Unauthorized methods, objects, or data become accessible |
These classes overlap but require sink-specific defenses. HTML encoding does not make a shell command safe, and SQL parameterization does not protect a template engine.
Common causes
- Passing request parameters, headers, cookies, files, or stored data into
eval-like features. - Building code, templates, queries, or shell commands through string concatenation.
- Allowing user-controlled module names, class names, callbacks, reflection, or plugin paths.
- Unsafe deserialization that reconstructs attacker-selected objects or invokes dangerous behavior.
- Generating scripts or expressions from database content that was never trusted.
- Relying on blocklists of a few characters while alternate syntax, encoding, or execution paths remain.
Stored input can become dangerous later when a background job, administrator panel, report generator, or template renderer interprets it. Validate trust at every execution boundary, not only when data first enters the system.
Potential impact
- Execution of arbitrary application code or operating-system commands.
- Reading secrets, configuration, source code, databases, and cloud credentials.
- Changing data, creating accounts, modifying payments, or bypassing authorization.
- Installing a web shell, miner, backdoor, or ransomware payload.
- Using the compromised service identity to access internal systems.
- Denial of service through resource exhaustion or destructive instructions.
The actual scope depends on the vulnerable process's privileges, network reach, secrets, filesystem permissions, and isolation.
How to prevent code injection
- Remove dynamic execution. Replace evaluation of constructed code with explicit functions, data structures, parsers, and fixed control flow.
- Use structured APIs. Apply prepared statements for SQL, argument-array process APIs instead of shells, contextual output encoding for browsers, and safe template modes.
- Allowlist choices. Map a small set of accepted user values to trusted internal actions. Do not let users provide executable names, classes, templates, or expressions directly.
- Validate input by grammar and context. Enforce expected type, length, range, encoding, and format. Canonicalize once using a well-defined parser.
- Apply least privilege. Run the service without administrator rights, minimize filesystem and network access, separate tenants, and restrict cloud identities.
- Harden dangerous features. Disable unused interpreters, template functions, plugin loaders, and runtime compilation in production.
- Keep dependencies updated. Framework and template-engine vulnerabilities can introduce injection even when application code looks safe.
Escaping is contextual and fragile. Prefer designs in which untrusted values never enter an executable string.
How to detect and test for injection
- During code review, trace untrusted sources to execution sinks and verify the transformation between them.
- Use static analysis rules for dangerous evaluators, shell APIs, template compilation, and unsafe deserialization.
- Run dynamic and interactive testing in an authorized non-production environment.
- Fuzz parsers and boundary conditions with safe test cases and monitor unexpected evaluator errors.
- Log rejected input and unusual child processes without storing secrets or complete attacker payloads.
- Alert when application servers spawn shells, scripting engines, download tools, or unfamiliar interpreters.
Incident response after suspected exploitation
- Contain affected instances and preserve requests, application logs, process trees, network activity, files, and cloud audit records.
- Identify the vulnerable sink, earliest known exploit, affected versions, tenants, and exposed privileges.
- Block exploitation at the application and edge as a temporary measure, then remove the unsafe code path.
- Rotate secrets reachable by the process and revoke suspicious sessions, tokens, keys, and service credentials.
- Hunt for web shells, persistence, new users, altered data, payloads, lateral movement, and exfiltration.
- Rebuild compromised systems from trusted artifacts and validate the permanent fix with regression tests.
Frequently asked questions
Is code injection always remote code execution?
No. The injected language or sandbox may limit capabilities. However, any attacker-controlled execution is serious and may be chained with other weaknesses.
Does sanitizing special characters prevent injection?
Not reliably across languages and contexts. Avoid the interpreter, use structured APIs, and allowlist narrowly defined values.
Is code injection the same as SQL injection?
SQL injection is a specific injection class targeting database queries. Code injection usually refers to execution in a programming-language runtime.