SQL Injection: The Complete Practical Guide
WAF and Filter Evasion for SQL Injection
Bypass keyword blacklists and WAFs: case and inline-comment obfuscation, encoding, whitespace alternatives, logical-operator swaps, and parameter pollution, step by step.
Published
A WAF or a hand-rolled keyword blacklist tries to spot SQL injection by pattern. The weakness is that SQL has many equivalent ways to write the same thing, so a filter that blocks one spelling rarely blocks them all. Evasion is the craft of expressing a payload the database understands but the filter does not.
How keyword blacklists fail
Blacklists match literal tokens: UNION, SELECT, OR, a space, a quote. SQL does not care about case, tolerates comments mid-keyword, and accepts several characters as whitespace. Every one of those is a gap. First, probe to learn what is blocked: send UNION, then SELECT, then a lone quote, and see which trips the filter. Then rewrite only the blocked tokens.
Case and inline-comment obfuscation
Case never matters to SQL, and most engines allow a /* */ comment inside a token:
SeLeCt UnIoN
UN/**/ION SEL/**/ECTThe database reads UNION SELECT, but a filter matching the exact uppercase string does not.
Encoding
Re-encode the characters the filter inspects so they arrive decoded only at the database:
%27 single URL-encoded quote
%2527 double URL-encoding (decoded twice)
0x61646d696e hex literal for 'admin' (MySQL)
CHAR(97,100,...) build a string from character codesDouble encoding is useful when one layer decodes before the filter and another decodes after it.
Whitespace alternatives
If spaces are stripped or flagged, swap them:
UNION(SELECT(1)) parentheses remove the need for spaces
UN/**/ION inline comment as a separator
%0a %0b %0c %a0 newline, vertical tab, form feed, non-breaking spaceLogical-operator equivalents
When OR and AND are blocked, use their symbolic forms or other operators:
OR -> || AND -> &&
= -> LIKE / IN
' OR 1=1 -> '||1=1 or ' OR 1 LIKE 1Chunked, overlong, and parameter-pollution bypasses
Some WAFs only inspect the first N bytes, so a long junk prefix can push the payload past the inspected window. HTTP parameter pollution splits a payload across repeated parameters (?id=1&id=UNION...) that the app concatenates but the WAF evaluates separately. And a no-space construction ties several tricks together:
'OR(1)=(1)-- -Treat these as a toolbox: identify the blocked token, pick the cheapest equivalent, reassemble. The cheat sheet has the quick list.
Practice slipping past a filter on a live target.