Code Injection
ID |
javascript.code_injection |
Severity |
critical |
Resource |
Injection |
Language |
JavaScript |
Tags |
CWE:95, NIST.SP.800-53, OWASP:2021:A3, PCI-DSS:6.5.1 |
Description
Improper neutralization of directives in dynamically evaluated code ('Eval Injection').
Code Injection vulnerabilities occur when an application dynamically executes code containing untrusted input from users.
Rationale
Functions like eval()
, setInterval
or the Function
constructor allow to execute arbitrary JavaScript code passed as a string:
const express = require('express');
const app = express();
app.get('/code_injection', (req, res) => {
let operationId = req.query.operation
// Dynamic execution of unvalidated user-controlled code
eval( `run_${operationId}()` ) // FLAW
res.send("Operation " + operationId + " executed")
});
In the example above, an attacker can choose arbitrary code injected in the 'operation' query parameter, so instead of running any run_<operation>()
function, the attacker can use delimiters like ';' or '&&' to run unintended JavaScript code, e.g. with operation=validOp(); evil_code //
.
Remediation
To mitigate Code Injection vulnerabilities, follow these best practices:
-
Avoid Dynamic Code Execution: Where possible, avoid using dynamic script execution or reflection with untrusted input.
-
Input Validation and Sanitization: Assume all input is potentially malicious. Rigorously validate all user inputs to confirm they adhere to expected formats, and sanitize them (a whitelisting approach is recommended) to remove potentially harmful content.
-
Canonicalization: Decode and canonicalize inputs to a standard internal representation before validation. This helps prevent bypassing input filters through encoding tricks
In the example above, eval could be used, but with a strict whitelist of the commands allowed:
const express = require('express');
const app = express();
// Whitelisting valid operations
app.get('/code_injection_fixed', (req, res) => {
let operationId = req.query.operationId || ''
// FIXED
if( operationId.matches(/^(create|remove|update)$/i) ) {
eval( `run_${operationId}()` )
res.send("Operation " + operationId + " executed")
} else {
res.send("Invalid operation")
}
});
Configuration
The detector has the following configurable parameters:
-
sources
, that indicates the source kinds to check. -
neutralizations
, that indicates the neutralization kinds to check.
Unless you need to change the default behavior, you typically do not need to configure this detector.
References
-
CWE-95 : Improper Neutralization of Directives in Dynamically Evaluated Code ('Eval Injection').
-
OWASP Top 10 2021 - A03 : Injection.
-
OWASP Code Injection explained.