TechEarl

sqlmap Evasion and Anti-Detection: WAF Bypass in Practice

How to get sqlmap past commercial WAFs. Tamper scripts that still work, request shaping (delays, chunked encoding, HPP), fingerprint reduction, when tamper chains fail and you need to drop to manual Burp Repeater, and the defender's view of what these techniques look like in the logs.

Ishan Karunaratne⏱️ 10 min readUpdated
Share thisCopied
sqlmap evasion techniques against modern WAFs: tamper scripts, request shaping, and manual fallbacks

Most production targets today sit behind a WAF. Cloudflare, AWS WAF, Akamai, Imperva, Fastly, or a self-hosted ModSecurity. Default sqlmap against any of them gets identified inside the first three requests, the source IP gets challenge-rated or blocked, and your scan is dead before it started.

This is the practical evasion playbook. Tamper scripts that still work today, request shaping that survives modern signature engines, fingerprint reduction at the protocol level, and the point at which you should stop fighting sqlmap and switch to manual exploitation in Burp Repeater.

If you have not read the sqlmap cheat sheet, the tamper script references below will make more sense after. Background on the variants is in the SQL injection deep dive.

What WAFs actually catch

Modern WAFs combine three detection layers:

  1. Signature matching. Regex and lexer-based rules looking for SQL keywords, comment markers, payload patterns. The OWASP CRS (Core Rule Set) is the open reference; commercial engines layer their own on top.
  2. Reputation and fingerprint. User-Agent, TLS fingerprint (JA3/JA4), HTTP/2 frame ordering, request timing patterns. A client that "looks like sqlmap" gets flagged before the payload is even inspected.
  3. Behavioural and ML. Rate of requests, parameter-value entropy, response-size variance. Aggressive scans tip the behavioural signals even when individual payloads are clean.

Evasion has to address all three. A clever tamper script that defeats signatures is useless if your TLS fingerprint screams "Python requests library" on connection.

Step 1: identify the WAF

Before evasion, know what you are evading. sqlmap's built-in detector:

bash
sqlmap -u 'https://target.example/product?id=1' --identify-waf

Output names the WAF if recognised:

code
[INFO] heuristics detected web page charset 'utf-8'
[INFO] WAF/IPS identified as 'Cloudflare (Cloudflare Inc.)'

wafw00f is the standalone tool with broader signatures and is worth running as a cross-check:

bash
wafw00f https://target.example/

Knowing the WAF tells you which tamper scripts to try first. Cloudflare and AWS WAF respond well to different obfuscations.

Step 2: tamper scripts that still work

sqlmap ships with around fifty tamper scripts. Most were written against specific WAF versions and have aged unevenly. These are the ones I find still pulling weight today, grouped by what they do:

Whitespace and comment obfuscation:

TamperWhat it doesDefeats
space2commentReplaces spaces with /**/Basic CRS, naive blacklists
space2plusReplaces spaces with +Some URL-encoded contexts
space2randomblankRandom tab/newline/whitespaceLexers that only match literal space
space2dashReplaces spaces with -- <random>\nSame family
betweenReplaces > with NOT BETWEEN 0 AND #WAFs that block > specifically

Case and encoding:

TamperWhat it doesDefeats
randomcaseSeLeCt-style random caseCase-sensitive blacklists (rare but still seen)
charencodeHex-encode payloadNaive ASCII-only signatures
charunicodeencodeUnicode escape keywordsUnicode-unaware lexers
charunicodeescapeSame family, different encodingSame
equaltolike= becomes LIKE= blacklists

MySQL-specific:

TamperWhat it doesDefeats
versionedkeywords/*!UNION*/Old ModSec rules
versionedmorekeywordsMore aggressive versioned commentsSame
halfversionedmorekeywordsVersioned comments before each keywordMore aggressive variant
apostrophenullencode' becomes %00%27WAFs that miss null bytes

Chains worth trying:

Cloudflare currently (heuristic, varies by ruleset version):

bash
--tamper=between,randomcase,space2comment

AWS WAF managed rules:

bash
--tamper=charunicodeencode,space2randomblank,randomcase

ModSecurity with CRS 3.x (still common in self-hosted):

bash
--tamper=modsecurityversioned,space2comment,randomcase

Cycle through chains. A combination that worked last month may not work this month if the WAF vendor pushed updates.

Tamper scripts I would not bother with anymore:

  • appendnullbyte, most modern stacks handle null bytes safely now.
  • halfversionedmorekeywords outside MySQL, most other DBMS do not parse versioned comments at all.
  • multiplespaces, almost no current WAF cares about multiple spaces.

Step 3: request shaping

Tamper scripts change the payload. Request shaping changes the request envelope around it. Both matter.

Pacing:

bash
--delay=5 --threads=1 --timeout=30 --retries=3

Slow enough that behavioural detection treats you as a human-paced client. --delay=5 adds five seconds between requests. With --threads=1 you get a steady five-second cadence. Forget about scan time; you are buying detection-rate reduction.

User-Agent and headers:

bash
--random-agent
-H "Accept-Language: en-US,en;q=0.9"
-H "Accept-Encoding: gzip, deflate, br"
-H "Cache-Control: max-age=0"
-H "Upgrade-Insecure-Requests: 1"

Default sqlmap headers are sparse. Real browsers send a dozen headers. Pad with realistic values to reduce header-shape fingerprinting.

HTTP parameter pollution (HPP):

bash
--hpp

Splits payloads across duplicate parameters: ?id=1&id=UNION&id=SELECT.... Different servers reassemble these differently. PHP takes the last, Java's getParameter takes the first, ASP.NET concatenates with commas. WAFs that reassemble differently from the application miss the payload entirely.

Chunked transfer encoding:

bash
--chunked

Splits POST bodies via Transfer-Encoding: chunked. Some WAFs do not reassemble before inspection; the application does. Less effective than it used to be because mature WAFs handle chunked now, but worth trying when the WAF identifies as something older.

HEAD-based detection:

bash
--null-connection

Use HEAD requests for boolean detection. The WAF often inspects fewer headers on HEAD, and content-length differences alone signal true/false without body content for the WAF to match against.

Step 4: TLS and HTTP fingerprint reduction

This is where sqlmap's defaults betray you. Python's requests library (which sqlmap uses) has a JA3 TLS fingerprint that every commercial WAF recognises. No tamper script fixes this.

Options:

curl-impersonate is the easiest fix. It is a build of curl with patched TLS and HTTP/2 stacks that match real browsers' fingerprints. Use it as a per-request fetcher via sqlmap's --eval or roll a small wrapper:

bash
# Pseudo-pattern (sqlmap does not natively use curl-impersonate, so you wrap):
# Capture sqlmap requests, replay through curl-impersonate, return responses.

Honest assessment: this is awkward to bolt onto sqlmap. The realistic options when TLS fingerprinting is the blocker are:

  1. Burp Suite as the relay. Run sqlmap through Burp (--proxy=http://127.0.0.1:8080). Burp's TLS stack is browser-like enough to pass most fingerprint checks. You lose some speed; you gain fingerprint legitimacy.
  2. Drop to manual. If TLS fingerprinting is being aggressively used, you are dealing with a hardened target and the productivity gain of sqlmap is gone. Burp Repeater plus hand-crafted payloads through a real browser session is the alternative.

Step 5: avoid sqlmap's tells

sqlmap leaves signatures even when payloads are obfuscated:

  • Sequential parameter probing. sqlmap tests one parameter at a time with predictable payload progression. Behavioural detection latches onto this. Mitigate with -p to restrict to one parameter at a time across separate runs.
  • information_schema access. sqlmap reaches for information_schema for enumeration. Even with tampered keywords, the volume of metadata queries from one source IP is the signal. Slow down with --threads=1 --delay=5.
  • Predictable request ordering. ORDER BY probing, column-count probing, and union enumeration each have characteristic request shapes. Spreading across multiple sessions and IPs (Tor exit rotation, see the Tor guide) breaks the per-source pattern but does not change the global pattern.

Step 6: when to give up on sqlmap

I switch to manual when any of:

  • Three tamper-chain combinations fail to get past the WAF.
  • The TLS fingerprint is being used as a primary block (sqlmap returns identical 403/challenge regardless of payload).
  • The target is custom enough that sqlmap's payload templates do not fit (unusual encodings on the wire, gRPC, GraphQL with depth checks, or a JWT-signed parameter where the WAF is checking the signature).

The manual fallback workflow:

  1. Confirm injection with three hand-crafted payloads in Burp Repeater (one boolean, one error-trigger, one time-based).
  2. Build a manual extraction loop using Burp Intruder (Pro) or a small Python script. Read one character of one column at a time with explicit conditional payloads.
  3. For a fully-blind target through a heavy WAF, the manual loop with hand-shaped payloads will be slower than sqlmap on an unprotected target but faster than sqlmap getting blocked every fifty requests.

This is unglamorous and accounts for maybe 10% of my SQLi work. The other 90% is sqlmap with the right tamper chain.

What this looks like from the defender's side

If you are on the other side of this, the signals that should fire:

  • WAF logs showing one source-IP cycling tamper-encoded payloads. Even when individual requests pass, the cluster across requests is the signal. A SIEM rule counting "payloads that look encoded" per source per hour is the right shape.
  • Application logs showing information_schema access from an account that should not need it. This is the highest-value detection rule for SQLi exploitation. Easy to write, near-zero false positive rate.
  • Behavioural rate anomalies. A single client making thousands of requests to the same parameter with varying value lengths matches the binary-search shape regardless of payload obfuscation.
  • TLS fingerprint that does not match a known browser combined with parameter-heavy traffic. A scan that defeats every payload signature still leaves a TLS fingerprint that, against your real user base, is anomalous.

Defenders: lean on the second one. Application-level alerts on suspicious database access are cheaper, more reliable, and harder to bypass than network-layer WAF rules.

A practical evasion order of operations

When sqlmap defaults get blocked, the order I try:

  1. --random-agent and realistic headers (Step 3).
  2. --delay=3 --threads=1 (slow down).
  3. A tamper chain matched to the identified WAF (Step 2).
  4. --hpp and --chunked (Step 3).
  5. Route through Burp as a proxy to launder the TLS fingerprint (Step 4).
  6. Drop to manual in Burp Repeater (Step 6).

If step 5 still fails, the target is hardened enough that scanning it without an explicit allow-list is a bad use of time. Get the IP whitelisted, scan from a known source, then unblock the harder work for engagements where the WAF itself is the test target.

Where to go next

Sources

Authoritative references this article was fact-checked against.

TagssqlmapWAF BypassEvasionTamper ScriptsPenetration TestingSecuritySQL Injection

Found this useful? Pass it on.

Copied

Ishan Karunaratne

Tech Architect · Software Engineer · AI/DevOps

Tech architect and software engineer with 20+ years building software, Linux systems, and DevOps infrastructure, and lately working AI into the stack. Currently Chief Technology Officer at a healthcare tech startup, which is where most of these field notes come from.

Keep reading

Related posts

SQL Injection: Variants, Exploitation, and Defence

How SQL injection actually works, what every major variant looks like (union-based, error-based, boolean blind, time blind, out-of-band, second-order, NoSQL), how to exploit each one against a vulnerable app, and how to defend against them at the code, query, and infrastructure layers.

sqlmap Cheat Sheet: Every Flag I Actually Use

A field-tested sqlmap reference: target specification, request shaping, detection tuning, DBMS fingerprinting, enumeration, dumping, file system access, OS command execution, evasion, and tamper scripts. Grouped by what you are actually trying to do.