CWE-95: Improper Neutralization of Directives in Dynamically Evaluated Code ('Eval Injection')
Learn about CWE-95 (Improper Neutralization of Directives in Dynamically Evaluated Code ('Eval Injection')), its security impact, exploitation methods, and prevention guidelines.
What is Improper Neutralization of Directives in Dynamically Evaluated Code ('Eval Injection')?
• Overview: This vulnerability occurs when an application improperly handles input in dynamic code evaluation functions like "eval", allowing attackers to execute arbitrary code within the application.
• Exploitation Methods:
- Attackers can exploit this vulnerability by crafting input that injects malicious code into the eval function.
- Common attack patterns include inserting commands or scripts that the application executes with high privileges.
• Security Impact:
- Direct consequences include unauthorized code execution, data leakage, or complete system compromise.
- Potential cascading effects could lead to further exploitation of other vulnerabilities or access to other network resources.
- Business impact includes data breaches, loss of customer trust, and potential legal liabilities.
• Prevention Guidelines:
- Specific code-level fixes involve avoiding the use of eval or similar functions for executing untrusted input.
- Security best practices include input validation, sanitization, and using safer alternatives to eval like interpreting specific logic or using libraries.
- Recommended tools and frameworks include static code analysis tools to detect unsafe eval usage and frameworks that inherently discourage or disable eval functionalities.
Technical Details
Likelihood of Exploit:
Affected Languages: Java, JavaScript, Python, Perl, PHP, Ruby, Interpreted
Affected Technologies: AI/ML
Vulnerable Code Example
// This code demonstrates a vulnerability where user input is directly evaluated.
// This can lead to arbitrary code execution if untrusted input is supplied.
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;
public class EvalService {
public Object evaluateUserInput(String userInput) throws ScriptException {
ScriptEngineManager manager = new ScriptEngineManager();
ScriptEngine engine = manager.getEngineByName("JavaScript");
// Vulnerable: Directly evaluating user input without validation
return engine.eval(userInput);
}
}
How to fix Improper Neutralization of Directives in Dynamically Evaluated Code ('Eval Injection')?
The vulnerability arises from directly evaluating user input without any validation or sanitization, which can lead to execution of arbitrary code. To fix this, avoid evaluating dynamic code from untrusted sources. If dynamic evaluation is necessary, strictly validate input against a whitelist of allowed operations or use a safer alternative.
Consider the following best practices:
- Avoid Dynamic Code Execution: Refrain from using
eval
if possible. Use predefined functions or logic instead. - Input Validation: If
eval
is unavoidable, strictly validate input using a whitelist approach. - Use Sandboxing: Execute potentially dangerous code in a sandboxed environment to limit its capabilities.
- Least Privilege: Ensure the execution environment has the least privilege necessary.
- Use a Safer API: If feasible, use APIs or libraries designed to safely handle untrusted input.
Fixed Code Example
// Fixed code with validation checks and disabling dynamic code execution
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;
import java.util.Set;
public class EvalService {
// Whitelist of safe functions
private static final Set<String> ALLOWED_FUNCTIONS = Set.of("Math.sqrt", "Math.pow");
public Object evaluateUserInput(String userInput) throws ScriptException {
// Validate input against a whitelist of allowed operations
if (!isValidInput(userInput)) {
throw new IllegalArgumentException("Invalid input provided");
}
ScriptEngineManager manager = new ScriptEngineManager();
ScriptEngine engine = manager.getEngineByName("JavaScript");
// Secure: Input is validated before evaluation
return engine.eval(userInput);
}
private boolean isValidInput(String input) {
// Check if the input starts with any of the allowed functions
return ALLOWED_FUNCTIONS.stream().anyMatch(input::startsWith);
}
}
In the fixed example:
- A whitelist (
ALLOWED_FUNCTIONS
) is used to validate if the input is permissible. - The
isValidInput
method checks that the input only contains safe operations before allowing it to be evaluated. - Direct evaluation of untrusted input is avoided, preventing execution of arbitrary or malicious code.