Run a Security Scan¶
Time: 5 minutes | Tools: security_scan | Tier: Community
Learn how to detect common vulnerabilities in your Python code.
What You'll Learn¶
- How taint analysis works
- Common vulnerability types
- Interpreting security results
- Fixing detected issues
Prerequisites¶
- Completed previous tutorials
- Sample code (see below)
Sample Vulnerable Code¶
Create vulnerable.py:
# vulnerable.py
import sqlite3
import os
def get_user(user_id):
"""Get user from database - VULNERABLE!"""
conn = sqlite3.connect("users.db")
cursor = conn.cursor()
# SQL Injection vulnerability
query = f"SELECT * FROM users WHERE id = {user_id}"
cursor.execute(query)
return cursor.fetchone()
def run_command(cmd):
"""Run a system command - VULNERABLE!"""
# Command injection vulnerability
os.system(cmd)
def read_file(filename):
"""Read a file - VULNERABLE!"""
# Path traversal vulnerability
with open(f"/data/{filename}") as f:
return f.read()
Step 1: Run the Scan¶
Ask your AI:
"Scan vulnerable.py for security issues"
The AI calls:
Step 2: Understand the Results¶
{
"data": {
"file_path": "vulnerable.py",
"vulnerabilities": [
{
"type": "SQL_INJECTION",
"severity": "CRITICAL",
"cwe": "CWE-89",
"line": 10,
"function": "get_user",
"source": "user_id (parameter)",
"sink": "cursor.execute(query)",
"taint_flow": [
"user_id (line 5) → tainted",
"query (line 9) → tainted via f-string",
"cursor.execute (line 10) → SINK"
],
"message": "User input flows directly to SQL execution",
"confidence": 0.95
},
{
"type": "COMMAND_INJECTION",
"severity": "CRITICAL",
"cwe": "CWE-78",
"line": 15,
"function": "run_command",
"source": "cmd (parameter)",
"sink": "os.system(cmd)",
"taint_flow": [
"cmd (line 13) → tainted",
"os.system (line 15) → SINK"
],
"message": "User input flows directly to system command",
"confidence": 0.98
},
{
"type": "PATH_TRAVERSAL",
"severity": "HIGH",
"cwe": "CWE-22",
"line": 20,
"function": "read_file",
"source": "filename (parameter)",
"sink": "open(f\"/data/{filename}\")",
"taint_flow": [
"filename (line 17) → tainted",
"open() (line 20) → SINK"
],
"message": "User input used in file path without sanitization",
"confidence": 0.90
}
],
"summary": {
"total": 3,
"critical": 2,
"high": 1,
"medium": 0,
"low": 0
}
},
"tier_applied": "community",
"duration_ms": 45
}
Understanding Taint Analysis¶
What is Taint?¶
"Taint" means data that could be controlled by an attacker:
| Taint Source | Example |
|---|---|
| Function parameters | def get_user(user_id) |
| HTTP requests | request.args.get('id') |
| File contents | open(file).read() |
| User input | input() |
What is a Sink?¶
A "sink" is a dangerous operation:
| Sink | Risk |
|---|---|
cursor.execute() | SQL injection |
os.system() | Command injection |
open() | Path traversal |
eval() | Code injection |
render() | XSS |
Taint Flow¶
The scan shows how tainted data reaches sinks:
Step 3: Fix the Vulnerabilities¶
Fix SQL Injection¶
Before:
After:
Fix Command Injection¶
Before:
After:
import subprocess
import shlex
# Validate allowed commands
ALLOWED_COMMANDS = {"ls", "pwd", "date"}
if cmd.split()[0] not in ALLOWED_COMMANDS:
raise ValueError("Command not allowed")
subprocess.run(shlex.split(cmd), check=True)
Fix Path Traversal¶
Before:
After:
import os
# Sanitize path
safe_path = os.path.normpath(filename)
if ".." in safe_path or safe_path.startswith("/"):
raise ValueError("Invalid filename")
full_path = os.path.join("/data", safe_path)
with open(full_path) as f:
Vulnerability Types¶
| Type | CWE | Severity | Example |
|---|---|---|---|
| SQL Injection | CWE-89 | Critical | f"SELECT ... {input}" |
| Command Injection | CWE-78 | Critical | os.system(input) |
| XSS | CWE-79 | High | render(f"<p>{input}</p>") |
| Path Traversal | CWE-22 | High | open(f"/data/{input}") |
| Code Injection | CWE-94 | Critical | eval(input) |
Try It Yourself¶
Exercise 1: Scan Your Own Code¶
"Scan [your_file.py] for security vulnerabilities"
Exercise 2: Check Dependencies¶
"Scan my requirements.txt for known vulnerabilities"
Uses scan_dependencies to check against CVE databases.
Exercise 3: Fix and Rescan¶
After fixing issues:
"Rescan vulnerable.py to verify the fixes"
Community Tier Limits¶
| Feature | Community |
|---|---|
| Single-file scan | ✅ |
| Max paths | 10 |
| Cross-file scanning | ❌ (Pro) |
| Custom sinks | ❌ (Enterprise) |
Key Takeaways¶
security_scanfinds vulnerabilities using taint analysis- Taint = data controlled by attackers
- Sink = dangerous operations
- Results show the full flow from source to sink
- Always use parameterized queries and input validation
Next Tutorial¶
Put everything together in a complete workflow: