How SQL Injection Actually Works (and How Parameterized Queries Stop It)
SQL injection has appeared in the OWASP Top 10 most critical web security risks for every year since the list was created. It has been responsible for some of the most significant data breaches in history, including attacks on major retailers, government databases, and financial institutions. Despite decades of awareness, it remains active because developers continue to build database queries by concatenating user input with SQL strings. Here is exactly how the attack works.
The Mechanics of an Injection Attack
Consider a login form that takes a username and password. The application constructs a SQL query by concatenating the user's input directly into the query string:
SELECT * FROM users WHERE username = ' + username + ' AND password = ' + password + '
If the user enters admin as the username and anything' OR '1'='1 as the password, the constructed query becomes:
SELECT * FROM users WHERE username = 'admin' AND password = 'anything' OR '1'='1'
The condition OR '1'='1' is always true. The entire WHERE clause evaluates to true for every row in the table. The query returns all users, and the application typically logs in as the first user returned — often the administrator.
Escalating to Data Exfiltration
A more sophisticated attacker does not stop at authentication bypass. Using UNION-based injection, they can append a second SELECT statement to extract data from other tables:
username' UNION SELECT username, password, null FROM admin_users --
The -- is a SQL comment that causes the remainder of the original query to be ignored. The UNION appends the results of the second SELECT to the first. If the application displays query results anywhere in the response, the attacker can read data from arbitrary tables including those containing user credentials, payment information, or personal records.
Why Input Sanitization Is Insufficient
Filtering or escaping user input is fragile defence. Character blacklists miss encoding variations: a single quote might be submitted as %27 (URL encoding), ' (HTML entity), or through multi-byte character sequences that some parsers interpret as a single quote. Security through string manipulation is a constant catch-up game against new bypass techniques.
Parameterized Queries: The Correct Solution
Parameterized queries (also called prepared statements) separate the SQL structure from the data. The query is sent to the database with placeholder markers, and the data values are sent separately. The database treats the data as data — it is never interpreted as SQL syntax.
The same login query written as a parameterized query:
SELECT * FROM users WHERE username = ? AND password = ?
The ? placeholders are filled by the database driver with the user-supplied values after the query structure has been compiled. No matter what the user submits, it is treated as a literal string value, not executable SQL. anything' OR '1'='1 becomes a literal string that the database attempts to match against the password column. It does not match, and the login fails.
Parameterized Queries in Practice
Every major database library in every language supports parameterized queries. They are not a performance penalty — prepared statements are often faster than ad-hoc queries because the query plan is compiled once and reused. There is no valid argument for not using them.
Use the USECALC SQL Formatter to clean and inspect SQL queries during development. Understanding query structure is the first step to building queries that cannot be injected against.