SQL Injection Explained
SQL injection (SQLi) is a code injection technique where an attacker manipulates SQL queries by inserting malicious input through application parameters. Despite being well-understood for over two decades, SQLi remains one of the most common and devastating web vulnerabilities because it can expose entire databases.
How SQL Injection Works
Consider a login query built by string concatenation:
query = "SELECT * FROM users WHERE username = '" + input + "' AND password = '" + password + "'"
If an attacker enters ' OR '1'='1 as the username, the query becomes:
SELECT * FROM users WHERE username = '' OR '1'='1' AND password = ''
The OR '1'='1' is always true, so the query returns all users — the attacker bypasses authentication entirely. This is the simplest SQLi, but the principle applies wherever user input is concatenated into SQL.
Types of SQL Injection
Classic (in-band): The result of the injected query is returned directly in the application's response. The attacker can use UNION SELECT to extract data from other tables.
Blind SQLi: The application does not return query results, but the attacker can infer data by observing differences in behaviour. Boolean-based blind SQLi observes true/false responses; time-based blind SQLi uses SLEEP() or BENCHMARK() to detect differences in response time.
Second-order SQLi: The malicious input is stored in the database and executed later when it is used in a different query. This is harder to detect because the injection point and the execution point are in different parts of the application.
Prevention: Parameterized Queries
The most effective defense is parameterized queries (prepared statements), where user input is passed as parameters that are never interpreted as SQL:
# Python (sqlite3)
cursor.execute("SELECT * FROM users WHERE username = ? AND password = ?", (username, password))
# Node.js (pg)
client.query("SELECT * FROM users WHERE username = $1 AND password = $2", [username, password])
# Java (JDBC)
PreparedStatement ps = conn.prepareStatement("SELECT * FROM users WHERE username = ? AND password = ?");
ps.setString(1, username);
ps.setString(2, password);
The database driver ensures the parameters are treated as data, never as SQL commands. This is the gold standard — use it everywhere. Validate your SQL query results as JSON using the JSON Formatter when building API responses from database data.
ORM Safety
Object-Relational Mappers (Django ORM, SQLAlchemy, ActiveRecord, Prisma) use parameterized queries internally, so standard ORM operations are safe from SQLi. However, ORMs also provide escape hatches for raw SQL — .raw(), .execute(), Arel.sql() — and these are just as vulnerable as manual string concatenation if you interpolate user input. Always use the ORM's parameterised raw query methods.
Defense in Depth
Parameterized queries are the primary defense, but defense in depth adds additional layers: input validation (reject unexpected characters for structured inputs like IDs and emails), least-privilege database accounts (the app's DB user should not have DROP TABLE or FILE permissions), WAF rules (catch common SQLi patterns at the edge), and error handling (never expose database error messages to users — they reveal table names, column names, and database version information).
Testing for SQL Injection
Test by injecting single quotes ('), double quotes ("), and SQL keywords into every parameter. Use time-based payloads (' OR SLEEP(5)--) to detect blind SQLi. Automated tools like sqlmap, Burp Suite, and OWASP ZAP can identify SQLi vulnerabilities systematically. Always test in a safe environment — never against production systems you do not own. Use the Unicode Converter to explore Unicode-based injection techniques, and the URL Encoder to understand how injected payloads are encoded in URLs.
Real-World Impact
SQL injection has caused some of the largest data breaches in history. The 2017 Equifax breach exposed 147 million records. The Heartland Payment Systems breach compromised 134 million credit cards. In both cases, SQL injection was the entry point. SQLi is not an academic exercise — it is an active, ongoing threat that automated bots exploit continuously against every internet-facing application.