Python Security Checks
These checks identify security vulnerabilities specific to Python code, including unsafe deserialization, code injection, and other Python-specific risks.
python-rce-eval
Severity: Critical
What It Detects
Use of eval() or exec() functions in Python.
Why It's Dangerous
Python's eval() and exec() execute arbitrary code, allowing attackers to run any Python code on your server.
Example Vulnerable Code
# User input executed as code
user_input = request.args.get('expression')
result = eval(user_input) # DANGEROUS!
# Dynamic code execution
code = request.json.get('code')
exec(code) # EXTREMELY DANGEROUS!Safe Alternative
# For math expressions
import ast
def safe_eval(expr):
# Only allow literals and basic operations
return ast.literal_eval(expr)
# For JSON
import json
data = json.loads(user_input)
# For configuration
import yaml
config = yaml.safe_load(config_string)python-rce-subprocess
Severity: Critical
What It Detects
Use of subprocess module with shell=True or user-controlled commands.
Why It's Dangerous
Shell execution allows command injection through special characters like ;, |, &&.
Example Vulnerable Code
import subprocess
# shell=True enables command injection
subprocess.run(f"ls {user_dir}", shell=True) # DANGEROUS!
# User-controlled command
subprocess.run(user_command, shell=True) # EXTREMELY DANGEROUS!Safe Alternative
import subprocess
import shlex
# Use list arguments (no shell interpretation)
subprocess.run(["ls", sanitized_dir])
# If shell is needed, use shlex
safe_cmd = shlex.quote(user_input)
subprocess.run(f"command {safe_cmd}", shell=True)python-rce-os-system
Severity: Critical
What It Detects
Use of os.system() or os.popen().
Why It's Dangerous
These functions execute shell commands and are vulnerable to injection.
Example Vulnerable Code
import os
os.system(f"rm {filename}") # DANGEROUS!
os.popen(f"cat {filepath}") # DANGEROUS!Safe Alternative
import os
import shutil
# Use Python's built-in functions
os.remove(safe_filename)
shutil.rmtree(safe_directory)
# For file reading
with open(safe_filepath) as f:
content = f.read()python-rce-pickle
Severity: High
What It Detects
Use of pickle.load() or pickle.loads() which can execute arbitrary code during deserialization.
Why It's Dangerous
Pickle can execute arbitrary Python code when loading data, making it unsafe for untrusted input.
Example Vulnerable Code
import pickle
# Loading untrusted pickle data
data = pickle.loads(user_data) # DANGEROUS!
with open(untrusted_file, 'rb') as f:
obj = pickle.load(f) # DANGEROUS!Safe Alternative
import json
# Use JSON for untrusted data
data = json.loads(user_data)
# Or use restricted unpickler
import pickle
import io
class RestrictedUnpickler(pickle.Unpickler):
def find_class(self, module, name):
raise pickle.UnpicklingError("Restricted")
def safe_pickle_load(data):
return RestrictedUnpickler(io.BytesIO(data)).load()python-rce-yaml
Severity: High
What It Detects
Use of yaml.load() without Loader=SafeLoader or yaml.safe_load().
Why It's Dangerous
YAML's default loader can instantiate arbitrary Python objects, leading to code execution.
Example Vulnerable Code
import yaml
# Unsafe YAML loading
data = yaml.load(user_input) # DANGEROUS!
data = yaml.load(user_input, Loader=yaml.Loader) # DANGEROUS!Safe Alternative
import yaml
# Use safe_load
data = yaml.safe_load(user_input)
# Or explicitly use SafeLoader
data = yaml.load(user_input, Loader=yaml.SafeLoader)python-injection-sql
Severity: High
What It Detects
SQL queries built with string concatenation or f-strings.
Why It's Dangerous
SQL injection can allow attackers to read, modify, or delete database data.
Example Vulnerable Code
# String concatenation
query = "SELECT * FROM users WHERE id = " + user_id
cursor.execute(query) # DANGEROUS!
# f-strings
query = f"SELECT * FROM users WHERE name = '{name}'"
cursor.execute(query) # DANGEROUS!Safe Alternative
# Use parameterized queries
cursor.execute(
"SELECT * FROM users WHERE id = %s",
(user_id,)
)
# With SQLAlchemy
from sqlalchemy import text
result = session.execute(
text("SELECT * FROM users WHERE id = :id"),
{"id": user_id}
)python-secrets-hardcoded
Severity: Critical
What It Detects
Hardcoded credentials in Python code:
- API keys
- Passwords
- Secret keys
Example Vulnerable Code
API_KEY = "sk-abc123..." # DANGEROUS!
PASSWORD = "super_secret" # DANGEROUS!Safe Alternative
import os
API_KEY = os.environ.get("API_KEY")
PASSWORD = os.environ.get("DB_PASSWORD")Other Python Checks
| Check | Severity | Description |
|-------|----------|-------------|
| python-rce-marshal | Medium | marshal module usage |
| python-rce-dynamic-import | High | __import__ or importlib |
| python-network-ssl-disabled | High | SSL verification disabled |
| python-fs-tempfile | Medium | Insecure temp file creation |
| python-fs-path-traversal | High | Path traversal patterns |
Summary
| Check | Severity | Key Fix | |-------|----------|---------| | python-rce-eval | Critical | Use ast.literal_eval or JSON | | python-rce-subprocess | Critical | Use list arguments, no shell | | python-rce-os-system | Critical | Use built-in Python functions | | python-rce-pickle | High | Use JSON or RestrictedUnpickler | | python-rce-yaml | High | Use yaml.safe_load | | python-injection-sql | High | Use parameterized queries | | python-secrets-hardcoded | Critical | Use environment variables |
Next Steps
- MCP Python - MCP checks for Python
- Reviewing Findings - How to fix issues
- API Reference - Automate scanning