Web Foundations & Databases · intermediate · ~12 min

SQL injection and prepared statements

Explain why string-built queries are injectable and how parameterization fixes it.

Overview

SQL injection occurs when input is concatenated into a query and changes its structure (' OR '1'='1, UNION SELECT). The fix is parameterized queries / prepared statements, which send SQL and data separately so input can't become code.

Why it matters

SQLi can dump or modify an entire database; it's a top web risk. Knowing the only correct remediation (parameterization, not escaping or WAFs) is essential for both finding and reporting it credibly.

Core concepts

Structure vs data. Injection turns input into query code. Payloads. ' OR '1'='1, UNION SELECT, stacked queries. Prepared statements. Bound parameters keep input as data. Defence-in-depth. Least-privilege DB user, validation; WAF ≠ fix.

Lesson

SQL injection (SQLi) happens when untrusted input is concatenated into a query so the input changes the query's structure, not just its data.

The bug

# VULNERABLE — input becomes part of the SQL text
q = "SELECT * FROM users WHERE name = '" + name + "'"

Input name = ' OR '1'='1 yields ... WHERE name = '' OR '1'='1' — true for every row. Worse inputs use UNION SELECT to exfiltrate other tables, or stacked queries to modify data.

The fix: prepared statements

Parameterized queries send the SQL structure and the data separately, so input can never become code:

# SAFE — ? is a bound parameter, not concatenated text
cur.execute("SELECT * FROM users WHERE name = ?", (name,))

The database treats name strictly as a value. This is the single correct fix — not blacklisting quotes, not escaping by hand.

Reporting note

When you find SQLi, the remediation is always parameterized queries / prepared statements (plus least-privilege DB accounts and input validation as defence-in-depth). "We added a WAF" is mitigation, not a fix.

Summary

SQL injection abuses string-built queries to alter their structure; prepared statements (parameterized queries) are the correct, complete fix because they separate code from data. Mirrors the platform's secure-coding C exercises.