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/**/ECT

The 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 codes

Double 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 space

Logical-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 1

Chunked, 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.

← Back to SQL Injection: The Complete Practical Guide