Cross-File Security Scanning¶
Time: 15 minutes | Tools: cross_file_security_scan | Tier: Pro
Learn to detect vulnerabilities where tainted data flows across file boundaries.
What You'll Learn¶
- Why single-file scanning misses vulnerabilities
- How cross-file taint tracking works
- Interpreting cross-file results
- Prioritizing fixes
The Problem¶
Single-file scanning misses this vulnerability:
# routes/auth.py
@app.route('/login', methods=['POST'])
def login():
username = request.form['username'] # Taint source
user = user_service.get_user(username) # Passes taint
return render_template('profile.html', user=user)
# services/user_service.py
def get_user(username):
return db_service.query_user(username) # Passes taint
# services/db_service.py
def query_user(username):
query = f"SELECT * FROM users WHERE name = '{username}'" # SINK!
return cursor.execute(query)
The taint flows across three files. Single-file scans see nothing wrong in any individual file!
Step 1: Run Cross-File Scan¶
"Scan the entire project for security vulnerabilities that span multiple files"
{
"tool": "cross_file_security_scan",
"parameters": {
"project_root": "./flask_app",
"max_depth": 5,
"include_diagram": true
}
}
Step 2: Understand the Results¶
{
"data": {
"vulnerabilities": [
{
"type": "SQL_INJECTION",
"severity": "CRITICAL",
"cwe": "CWE-89",
"confidence": 0.95,
"taint_flow": {
"source": {
"file": "routes/auth.py",
"line": 5,
"expression": "request.form['username']"
},
"path": [
{
"file": "routes/auth.py",
"line": 6,
"call": "user_service.get_user(username)"
},
{
"file": "services/user_service.py",
"line": 8,
"call": "db_service.query_user(username)"
}
],
"sink": {
"file": "services/db_service.py",
"line": 12,
"expression": "cursor.execute(query)"
}
},
"files_involved": [
"routes/auth.py",
"services/user_service.py",
"services/db_service.py"
]
}
],
"taint_diagram": "graph TD\n A[request.form - auth.py:5] --> B[get_user - user_service.py:8]\n B --> C[query_user - db_service.py:12]\n C --> D[cursor.execute - SINK!]",
"risk_assessment": {
"total_vulnerabilities": 1,
"critical": 1,
"high": 0,
"cross_file_vulns": 1,
"files_at_risk": 3
}
},
"tier_applied": "pro",
"duration_ms": 456
}
Step 3: Visualize the Flow¶
The scan generates a taint flow diagram:
graph TD
A["request.form['username']<br/>routes/auth.py:5"] --> B["get_user(username)<br/>user_service.py:8"]
B --> C["query_user(username)<br/>db_service.py:12"]
C --> D["cursor.execute(query)<br/>⚠️ SQL INJECTION"]
style A fill:#ffcccc
style D fill:#ff6666 Step 4: Understand the Risk¶
Why This Is Critical¶
- Attack vector: User-controlled input from a web form
- No sanitization: Data passes through unchanged
- Dangerous sink: Direct SQL execution
- Impact: Full database access, data theft, data manipulation
Attack Example¶
Becomes:
Returns all users!
Step 5: Fix the Vulnerability¶
Option 1: Fix at the Sink (Recommended)¶
# services/db_service.py
def query_user(username):
query = "SELECT * FROM users WHERE name = ?"
return cursor.execute(query, (username,)) # Parameterized
Option 2: Fix at the Source¶
# routes/auth.py
from utils.validators import sanitize_username
@app.route('/login', methods=['POST'])
def login():
username = sanitize_username(request.form['username'])
user = user_service.get_user(username)
return render_template('profile.html', user=user)
Option 3: Defense in Depth (Best)¶
Both! Sanitize at entry, parameterize at database.
Step 6: Verify the Fix¶
"Rescan the project for cross-file vulnerabilities"
After fixing:
{
"data": {
"vulnerabilities": [],
"risk_assessment": {
"total_vulnerabilities": 0,
"critical": 0,
"cross_file_vulns": 0
}
}
}
Common Cross-File Patterns¶
Pattern 1: Request → Service → Database¶
Risk: SQL Injection, NoSQL Injection
Pattern 2: Request → Template¶
Risk: XSS (Cross-Site Scripting)
Pattern 3: Request → Shell¶
Risk: Command Injection
Pattern 4: Request → File System¶
Risk: Path Traversal
Scan Configuration¶
Adjust Depth¶
{
"tool": "cross_file_security_scan",
"parameters": {
"project_root": ".",
"max_depth": 10 // Follow more call levels
}
}
Specify Entry Points¶
{
"tool": "cross_file_security_scan",
"parameters": {
"project_root": ".",
"entry_points": ["routes/auth.py:login", "routes/api.py:handle_request"]
}
}
Confidence Threshold¶
{
"tool": "cross_file_security_scan",
"parameters": {
"project_root": ".",
"confidence_threshold": 0.8 // Only high-confidence findings
}
}
Try It Yourself¶
Exercise 1: Scan Your Project¶
"Run a cross-file security scan on my project"
Exercise 2: Focus on Entry Points¶
"Scan for vulnerabilities starting from the API routes"
Exercise 3: Generate a Security Report¶
"Create a security report for this codebase"
Tier Requirements¶
| Feature | Community | Pro |
|---|---|---|
| Single-file scan | ✅ | ✅ |
| Cross-file scan | — | ✅ |
| Taint diagrams | — | ✅ |
| Entry point focus | — | ✅ |
| Custom thresholds | — | ✅ |
Key Takeaways¶
- Single-file scans miss cross-file vulnerabilities
- Taint flows through function calls across modules
- Visualize flows with the generated diagrams
- Fix at the sink (parameterized queries) is most reliable
- Defense in depth is best (sanitize AND parameterize)
Next Tutorial¶
Expand this workflow with the DevOps Guide to turn security scans into CI/CD gates.