1. String interpolation into raw SQL
Symptom
Added for a query the ORM couldn't express cleanly. Works perfectly and is fully injectable.
The pattern
cursor.execute(f"SELECT * FROM orders WHERE status = '{status}' ORDER BY {sort}")Why it bites
The f-string builds SQL before the driver sees it, so the driver cannot distinguish data from syntax. A status of `' OR '1'='1` returns every row; the sort parameter is worse, since it can carry an entire subquery.
The fix
# Parameterize values — the driver handles quoting and typing.
cursor.execute("SELECT * FROM orders WHERE status = %s", [status])
# Identifiers can't be parameterized. Allowlist them:
SORTABLE = {"created_at", "total", "status"}
if sort not in SORTABLE:
raise ValidationError("Invalid sort field")
cursor.execute(f"SELECT * FROM orders WHERE status = %s ORDER BY {sort}", [status])