Skip to content

python.unsafe_eval

Correctness Critical

Detects eval() or exec() calls with potentially untrusted input.

eval and exec execute arbitrary Python code. With untrusted input:

  • Remote code execution — Attackers run any code on your server
  • Data exfiltration — All your data can be copied out
  • System compromise — Can install backdoors, delete files, pivot to other systems
  • Total control — This is game over if exploited

This is one of the most severe security vulnerabilities possible.

# ❌ Before
result = eval(user_input)

If user_input is "__import__('os').system('rm -rf /')", you’ve just wiped your server.

# ✅ After (for data parsing)
import ast
result = ast.literal_eval(user_input)

ast.literal_eval only parses Python literals (strings, numbers, lists, dicts). It won’t execute code.

  • eval() with any variable input
  • exec() with any variable input
  • compile() with user input followed by exec
  • __import__() with variable arguments

For data parsing cases, Unfault replaces eval() with ast.literal_eval(). For other cases, manual review is required.

# For JSON data
import json
data = json.loads(user_input)
# For Python literals (strings, numbers, lists, dicts)
import ast
data = ast.literal_eval(user_input)
# For configuration
import yaml # with safe_load
config = yaml.safe_load(config_string)
# For math expressions (if really needed)
import numexpr
result = numexpr.evaluate(expression)
# NEVER eval user input, even "sanitized"
eval(user_input.replace(";", "")) # Still vulnerable
# NEVER use eval for JSON
eval(json_string) # Use json.loads
# NEVER use eval for config
eval(f"config['{key}']") # Use dict access