Understanding SQL Injection (A03:2021)

SQL Injection (SQLi) remains one of the most critical web vulnerabilities. It occurs when untrusted user input is directly concatenated into a database query, allowing attackers to manipulate the query structure.

The Vulnerability

Consider a legacy login system written in Python:

python
# VULNERABLE CODE - DO NOT USE
username = request.form['username']
query = f"SELECT * FROM users WHERE username = '{username}'"
cursor.execute(query)

If an attacker enters ' OR '1'='1, the query becomes SELECT * FROM users WHERE username = '' OR '1'='1', which is always true, potentially bypassing authentication.

Attack Flow

The following sequence diagram illustrates how an attacker exploits this vulnerability:

PlantUML Diagram

The Fix: Parameterized Queries

The most effective defense is using parameterized queries (also known as prepared statements). This ensures the database treats user input as data, not executable code.

python
# SECURE CODE
username = request.form['username']
# The '?' acts as a placeholder
query = "SELECT * FROM users WHERE username = ?"
cursor.execute(query, (username,))

By separating code from data, we neutralize the injection vector entirely.