id: PYTHON_SQL_FSTRING
severity: BLOCK
cwe:
- "CWE-89"
file_patterns:
- "*.py"
patterns:
- "f['\"]\\s*SELECT\\s.*FROM\\s.*\\{"
- "f['\"]\\s*INSERT\\s.*INTO\\s.*\\{"
- "f['\"]\\s*UPDATE\\s.*SET\\s.*\\{"
- "f['\"]\\s*DELETE\\s.*FROM\\s.*\\{"
- "f['\"].*\\bSELECT\\b.*\\bFROM\\b.*\\{"
- "f['\"].*\\bINSERT\\b.*\\bINTO\\b.*\\{"
- "f['\"].*\\bUPDATE\\b.*\\bSET\\b.*\\{"
- "f['\"].*\\bDELETE\\b.*\\bFROM\\b.*\\{"
case_insensitive: true
message: "SQL query constructed with f-string detected. F-string interpolation in SQL queries allows SQL injection. Any user-controlled variable in the f-string can manipulate the query."
fix: |
Use parameterized queries:
# WRONG (vulnerable):
cursor.execute(f"SELECT * FROM users WHERE id = {user_id}")
# RIGHT (safe):
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})
negation: false
exclude_paths:
- "test"
- "tests"
- "fixtures"
- "migrations"
category: "security"
metadata:
name: "Python SQL injection via f-string"
note: "F-strings are Python's most convenient string formatting but MUST NOT be used for SQL. This is the #1 Python SQL injection pattern generated by LLMs."