npx skills add ...
npx skills add yaklang/hack-skills --skill waf-bypass-techniques
WAF bypass methodology and generic evasion techniques. Use when a web application firewall blocks injection payloads (SQLi, XSS, RCE) and you need to craft bypasses using encoding, protocol-level tricks, or WAF-specific weaknesses.
npx skills add yaklang/hack-skills --skill waf-bypass-techniques
AI LOAD INSTRUCTION: Covers WAF identification, generic bypass categories (encoding, protocol abuse, HTTP/2, parameter pollution), and a decision tree. For product-specific bypasses (Cloudflare, AWS WAF, ModSecurity, Akamai, etc.), load WAF_PRODUCT_MATRIX.md. Base models often suggest basic encoding but miss protocol-level bypasses and WAF behavioral quirks.
char to 8-bit byte narrowing produces 255 Unicode bypass variants per dangerous ASCII byte; re-enables WAF-patched CVEs in Tomcat, Spring, Jetty, Jackson, Fastjson, BCEL, and moreLoad WAF_PRODUCT_MATRIX.md when you need per-product bypass techniques for Cloudflare, AWS WAF, ModSecurity CRS, Akamai, Imperva, F5 BIG-IP, or Sucuri.
Before bypassing, know what you're fighting.
| Tool | Usage |
|---|---|
wafw00f target.com | Fingerprint WAF vendor from response headers/behavior |
nmap --script=http-waf-detect | NSE script for WAF detection |
| Manual header inspection | Server, X-CDN, X-Cache, cf-ray (Cloudflare), x-sucuri-id, x-akamai-* |
| Technique | Example | Bypasses |
|---|---|---|
| URL encoding | %3Cscript%3E | Basic string matching |
| Double URL encoding | %253Cscript%253E | WAFs that decode once, app decodes twice |
| Unicode encoding | %u003Cscript%u003E | IIS-specific Unicode normalization |
| HTML entities | <script> or <script> | WAFs not performing HTML entity decoding |
| Hex encoding (SQL) | 0x756E696F6E = union | WAFs matching SQL keywords |
| Octal encoding | \74script\76 | Rare but some parsers handle it |
| Overlong UTF-8 | %C0%BC (invalid encoding for <) | Legacy parsers with loose UTF-8 handling |
| Mixed case | SeLeCt, uNiOn | Case-sensitive rule matching |
| Null byte | sel%00ect | WAFs that stop parsing at null |
Split the payload across HTTP chunks so no single chunk contains the blocked pattern:
WAFs that inspect the full body may not reassemble chunks before matching.
HTTP/2 transmits headers as binary HPACK-encoded frames. Some WAFs only inspect after downgrading to HTTP/1.1:
:method, :path) bypass header-based WAF rulesDifferent servers handle duplicate parameters differently:
| Server | Behavior for ?a=1&a=2 |
|---|---|
| PHP/Apache | Last value: a=2 |
| ASP.NET/IIS | Concatenated: a=1,2 |
| Python/Flask | First value: a=1 |
| Node.js/Express | Array: a=[1,2] |
WAF checks a=1 (benign), app uses a=2 (malicious). Or combine: a=sel&a=ect → ASP.NET sees a=sel,ect.
Headers trusted by some WAFs/apps for client IP:
Use case: WAF whitelists internal IPs or has different rule sets per source.
| Technique | Example | Effect |
|---|---|---|
| Dot segments | /./admin or /../target/admin | WAF sees different path than app |
| Double slash | //admin | Some normalizers collapse, WAFs may not |
| URL encoding path | /%61dmin | WAF sees encoded, app decodes |
| Null byte in path | /admin%00.jpg | Legacy: app truncates at null, WAF sees .jpg |
| Backslash (IIS) | /admin\..\/secret | IIS treats \ as / |
| Trailing dot/space | /admin. or /admin%20 | OS-level normalization (Windows) |
| Semicolon (Tomcat) | /admin;jsessionid=x | Tomcat strips after ;, WAF may not |
WAFs often have format-specific parsers. Switching Content-Type can bypass rules:
Trick: If app accepts both JSON and form-urlencoded, use JSON — WAFs often have weaker JSON inspection rules.
Variations: long boundary strings, boundary with special characters, missing final boundary, nested multipart.
| Blocked | Alternative |
|---|---|
UNION SELECT | UNION ALL SELECT, UNION DISTINCT SELECT |
OR 1=1 | OR 2>1, OR 'a'='a', ` |
<script> | <svg/onload=alert(1)>, <img src=x onerror=alert(1)> |
alert(1) | prompt(1), confirm(1), print() (Chrome) |
eval() | Function('code')(), setTimeout('code',0) |
' OR '1'='1 | ' OR 1-- -, '||'1 |
SLEEP(5) | BENCHMARK(5000000,SHA1('x')), pg_sleep(5) |
vs.
If WAF inspects original headers but app processes injected ones:
| Measure | Notes |
|---|---|
| WAF + application-level input validation | WAF is a layer, not a fix |
| Parameterized queries | Eliminates SQLi regardless of WAF |
| CSP + output encoding | Eliminates XSS regardless of WAF |
| Regularly update WAF rules | Vendor signatures lag behind new bypasses |
| Deny by default, not block-list | Allowlist valid input patterns |
| Log and alert on WAF blocks | Bypass attempts are visible in logs |