Attack Tuning¶
The default SQLMap settings are conservative — designed to be fast and avoid false positives. But in real engagements, you'll often need to tune the attack to handle complex scenarios. This section teaches you every knob and dial available.
Level and Risk — The Two Master Controls¶
These are the most important tuning parameters. Think of them as:
- Level = How broad is the testing? (How many parameters and payload patterns?)
- Risk = How aggressive is the testing? (Will it modify data?)
--level (1–5)¶
Controls the number of payloads used and which parameters are tested:
| Level | Parameters Tested | Payload Count | Time Estimate |
|---|---|---|---|
| 1 (default) | GET + POST body only | ~100 payloads per param | 1–5 minutes |
| 2 | + Cookie values | ~200 payloads per param | 5–10 minutes |
| 3 | + User-Agent, Referer headers | ~500 payloads per param | 10–30 minutes |
| 4 | + Additional header combinations | ~1000 payloads per param | 30–60 minutes |
| 5 | + Host header + all variations | ~5000+ payloads per param | 1–3 hours |
When to increase level:
- Level 2: When you suspect injection in a cookie value
- Level 3: When you suspect injection in a header (User-Agent, Referer)
- Level 5: When you're doing a thorough security assessment and want to test everything
--risk (1–3)¶
Controls the types of SQL injection techniques SQLMap will attempt:
| Risk | Techniques Added | Potential Side Effects |
|---|---|---|
| 1 (default) | AND-based, time-based | None — read-only tests |
| 2 | + OR-based tests | May return all rows from a table |
| 3 | + UPDATE-based tests | Can modify data in the database! |
Risk 3 Warning
Risk 3 includes UPDATE-based injection tests. This means SQLMap may execute queries like:
If the condition fails, the UPDATE still runs and modifies the admin's email. Only use risk 3 when:
- You have explicit authorization to modify data
- You have a database backup
- You're on a lab/staging environment
Technique Selection (--technique)¶
By default, SQLMap tries all 6 techniques: BEUSTQ. You can limit this to speed up scanning or target specific scenarios:
| Letter | Technique | Speed | Use Case |
|---|---|---|---|
B |
Boolean-based blind | Medium | Most universal |
E |
Error-based | Fast | When errors are visible |
U |
UNION query-based | Fastest | When output is displayed |
S |
Stacked queries | Variable | When you need DML/DDL |
T |
Time-based blind | Slowest | When nothing else works |
Q |
Inline queries | Variable | Rare, specific contexts |
Common Combinations¶
Custom Prefix and Suffix¶
Sometimes the injectable parameter is embedded in a SQL context that SQLMap doesn't automatically detect. You can tell SQLMap exactly how to wrap its payloads.
What Are Prefix and Suffix?¶
Imagine the server-side code looks like this:
The injection point is inside LIKE ('%...%'). SQLMap needs to:
- Close the existing context:
%')— this is the prefix - Comment out the rest:
-- -— this is the suffix
Common Prefix/Suffix Patterns¶
| SQL Context | Prefix | Suffix |
|---|---|---|
WHERE col = '$input' |
' |
-- - |
WHERE col = "$input" |
" |
-- - |
WHERE col = ($input) |
) |
-- - |
WHERE col = (('$input')) |
')) |
-- - |
WHERE col LIKE '%$input%' |
%' |
-- - |
ORDER BY $input |
(none) | -- - |
LIMIT $input |
(none) | -- - |
How to Figure Out the Context
If manual testing with ' produces an error like:
You have an error in your SQL syntax; check the manual that corresponds to your MySQL
server version for the right syntax to use near '%')' at line 1
The error message tells you the context! The %') at the end reveals the query uses LIKE ('%...'). Set your prefix accordingly.
UNION Query Tuning¶
When SQLMap detects UNION-based injection, it needs to determine the correct number of columns. You can help:
Specifying Column Count¶
If you already know the query has 5 columns:
Specifying Column Range¶
If you want SQLMap to test a specific range:
Specifying the Character Used¶
By default, SQLMap uses NULL for unused columns. Some databases reject NULL:
Specifying FROM Table¶
Oracle requires a FROM clause in every SELECT. SQLMap handles this automatically, but you can specify it:
Time-Based Blind Tuning¶
Adjusting the Delay Duration¶
The --time-sec flag controls how many seconds SQLMap waits for time-based blind injection:
How to choose:
- If your normal response time is <500ms,
--time-sec=2works - If your normal response time is 1-2 seconds, use
--time-sec=5(default) - If your normal response time is variable (3-5 seconds), use
--time-sec=10
The Latency Trap
If the target server has high latency (e.g., 3 seconds for a normal response), and you set --time-sec=2, SQLMap will think every response is a delayed response. This leads to completely wrong data extraction. Always set --time-sec to be at least 2x your normal response time.
Controlling What SQLMap Injects¶
Custom Injection Payloads (--tamper)¶
Tamper scripts modify the payload before sending. This is covered in detail in Bypassing Web Application Protections, but here are the basics:
Second-Order Injection¶
In second-order injection, the payload is stored in one location and executed in another. For example:
- You inject
admin'--as your username during registration - The injection triggers when an admin views your profile (different URL)
SQLMap supports this with --second-url:
sqlmap -r registration_request.txt \
--second-url="http://target.com/admin/view_users.php" \
--batch
Or if the result appears in a specific response:
Request Rate Control¶
Fixed Delay¶
Random Delay¶
Safe URL (Keep Session Alive)¶
sqlmap -r request.txt \
--safe-url="http://target.com/dashboard" \
--safe-freq=10
Throttle Based on Response¶
Page Comparison Tuning¶
When SQLMap compares TRUE vs FALSE responses, you can help it:
String Matching¶
Regex Matching¶
HTTP Status Code Matching¶
Text-Only Comparison¶
Strip all HTML tags and compare just the text content:
Title-Only Comparison¶
Compare only the <title> tag content:
Putting It All Together: Expert-Level Scan¶
Here's a command that uses multiple tuning options for a difficult target:
sqlmap -r request.txt \
--level=5 \
--risk=2 \
--dbms=mysql \
--technique=BEU \
--prefix="')" \
--suffix="-- -" \
--string="Products found" \
--tamper=space2comment,between \
--threads=5 \
--time-sec=3 \
--delay=0.5 \
--batch \
-v 3
This tells SQLMap:
- Test everything aggressively (
--level=5 --risk=2) - Target MySQL specifically
- Use Boolean, Error, and UNION techniques only (skip slow ones)
- The injection context needs
')prefix and-- -suffix - TRUE responses contain "Products found"
- Modify payloads to bypass filters
- Use 5 threads with 0.5s delay between requests
- Show all payloads for learning (
-v 3)