222
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().
Phase: Testing
Use automated static analysis tools that target this type of weakness. Many modern techniques
use data flow analysis to minimize the number of false positives. This is not a perfect solution,
since 100% accuracy and coverage are not feasible.
Phase: Testing
Use 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.
Phase: Operation
Strategy = Compilation or Build Hardening
Run 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).
Phase: Operation
Strategy = Environment Hardening
Run 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).
Phase: Implementation
For 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].
Effectiveness = Discouraged Common Practice
Demonstrative Examples
Example 1:
This example attempts to write user messages to a message file and allow users to view them.
Example Language: PHP (Bad)
$MessageFile = "messages.out";
if ($_GET["action"] == "NewMessage") {
$name = $_GET["name"];
$message = $_GET["message"];
$handle = fopen($MessageFile, "a+");
fwrite($handle, "<b>$name</b> says '$message'<hr>\n");
fclose($handle);
echo "Message Saved!<p>\n";
}
else if ($_GET["action"] == "ViewMessages") {
CWE Version 4.14
CWE-94: Improper Control of Generation of Code ('Code Injection')
CWE-94: Improper Control of Generation of Code ('Code Injection')