CWE-95: Improper Neutralization of Directives in Dynamically Evaluated Code ('Eval Injection')
Improper Neutralization of Directives in Dynamically Evaluated Code ('Eval Injection')
Weakness ID: 95 (Weakness Base)
Status: Incomplete
Description
Description Summary
The software receives input from an upstream component, but it does not neutralize or incorrectly neutralizes code syntax before using the input in a dynamic evaluation call (e.g. "eval").
Extended Description
This may allow an attacker to execute arbitrary code, or at least modify what code can be executed.
Time of Introduction
Architecture and Design
Implementation
Applicable Platforms
Languages
Java
Javascript
Python
Perl
PHP
Ruby
Interpreted Languages
Modes of Introduction
This weakness is prevalent in handler/dispatch procedures that might want
to invoke a large number of functions, or set a large number of
variables.
Common Consequences
Scope
Effect
Confidentiality
Technical Impact: Read files or
directories; Read application
data
The injected code could access restricted data / files.
Access Control
Technical Impact: Bypass protection
mechanism
In some cases, injectable code controls authentication; this may lead
to a remote vulnerability.
Access Control
Technical Impact: Gain privileges / assume
identity
Injected code can access resources that the attacker is directly
prevented from accessing.
Integrity
Confidentiality
Availability
Other
Technical Impact: Execute unauthorized code or
commands
Code injection attacks can lead to loss of data integrity in nearly
all cases as the control-plane data injected is always incidental to
data recall or writing. Additionally, code injection can often result in
the execution of arbitrary code.
Non-Repudiation
Technical Impact: Hide activities
Often the actions performed by injected control code are
unlogged.
Likelihood of Exploit
Medium
Demonstrative Examples
Example 1
edit-config.pl: This CGI script is used to modify settings in a
configuration file.
(Bad Code)
Example
Language: Perl
use CGI qw(:standard);
sub config_file_add_key {
my ($fname, $key, $arg) = @_;
# code to add a field/key to a file goes here
}
sub config_file_set_key {
my ($fname, $key, $arg) = @_;
# code to set key to a particular file goes here
}
sub config_file_delete_key {
my ($fname, $key, $arg) = @_;
# code to delete key from a particular file goes
here
}
sub handleConfigAction {
my ($fname, $action) = @_;
my $key = param('key');
my $val = param('val');
# this is super-efficient code, especially if you have to
invoke
# any one of dozens of different functions!
my $code = "config_file_$action_key(\$fname, \$key,
\$val);";
eval($code);
}
$configfile = "/home/cwe/config.txt";
print header;
if (defined(param('action'))) {
handleConfigAction($configfile, param('action'));
}
else {
print "No action specified!\n";
}
The script intends to take the 'action' parameter and invoke one of a
variety of functions based on the value of that parameter -
config_file_add_key(), config_file_set_key(), or
config_file_delete_key(). It could set up a conditional to invoke each
function separately, but eval() is a powerful way of doing the same
thing in fewer lines of code, especially when a large number of
functions or variables are involved. Unfortunately, in this case, the
attacker can provide other values in the action parameter, such
as:
(Attack)
add_key(",","); system("/bin/ls");
This would produce the following string in handleConfigAction():
(Result)
config_file_add_key(",","); system("/bin/ls");
Any arbitrary Perl code could be added after the attacker has "closed
off" the construction of the original function call, in order to prevent
parsing errors from causing the malicious eval() to fail before the
attacker's payload is activated. This particular manipulation would fail
after the system() call, because the "_key(\$fname, \$key, \$val)"
portion of the string would cause an error, but this is irrelevant to
the attack because the payload has already been activated.
chain: Resultant eval injection. An invalid value
prevents initialization of variables, which can be modified by attacker and
later injected into PHP eval statement.
Chain: Execution after redirect triggers eval
injection.
Potential Mitigations
Phases: Architecture and Design; Implementation
If possible, refactor your code so that it does not need to use eval()
at all.
Phase: Implementation
Strategy: Input Validation
Assume all input is malicious. Use an "accept known good" input
validation strategy, i.e., use a whitelist 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
(i.e., do not rely on a blacklist). A blacklist 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, blacklists can be useful for detecting potential
attacks or determining which inputs are so malformed that they should be
rejected outright.
Phase: Implementation
Inputs should be decoded and canonicalized to the application's current internal representation before being validated (CWE-180, CWE-181). Make sure that your application does not inadvertently decode the same input twice (CWE-174). Such errors could be used to bypass whitelist schemes by introducing dangerous inputs after they have been checked. Use libraries such as the OWASP ESAPI Canonicalization control.
Consider performing repeated canonicalization until your input does
not change any more. This will avoid double-decoding and similar
scenarios, but it might inadvertently modify inputs that are allowed to
contain properly-encoded dangerous content.
Other Notes
Factors: special character errors can play a role in increasing the
variety of code that can be injected, although some vulnerabilities do not
require special characters at all, e.g. when a single function without
arguments can be referenced and a terminator character is not
necessary.
Weakness Ordinalities
Ordinality
Description
Primary
(where
the weakness exists independent of other weaknesses)
This issue is probably under-reported. Most relevant CVEs have been for
Perl and PHP, but eval injection applies to most interpreted languages.
Javascript eval injection is likely to be heavily under-reported.
[REF-7] Mark Dowd, John McDonald
and Justin Schuh. "The Art of Software Security Assessment". Chapter 18, "Inline Evaluation", Page
1095.. 1st Edition. Addison Wesley. 2006.