When untrusted user input tricks your database into running it as code.
SQL Injection occurs when developers take raw text typed by a user and concatenate it directly into a SQL query string. A malicious user can type specially crafted characters (like quote marks and semicolons) to "break out" of the string and execute arbitrary database commands, such as stealing user data or deleting tables.
The only 100% effective way to stop SQL Injection is to use Parameterized Queries (or Prepared Statements). Instead of combining strings, you send the SQL template and the user data to the database separately. The database guarantees the data is treated purely as data, never as executable code.
# VULNERABLE: String Concatenation
user_id = "105 OR 1=1"
# Executes: SELECT * FROM users WHERE id = 105 OR 1=1
db.execute(f"SELECT * FROM users WHERE id = {user_id}")
# SECURE: Parameterized Query
user_id = "105 OR 1=1"
# The DB knows '105 OR 1=1' is just a literal string, not a command.
db.execute("SELECT * FROM users WHERE id = %s", (user_id,))
A login form asks for Username and Password. The code runs:
`"SELECT id FROM users WHERE user='" + username + "' AND pass='" + password + "'"`
The attacker types `' OR '1'='1` in both fields. The database executes:
`SELECT id FROM users WHERE user='' OR '1'='1' AND pass='' OR '1'='1'`
Since 1=1 is always true, the database returns the very first row (usually the Admin account), logging the attacker in without a password.
Which of the following defenses is the most robust against SQL Injection?