Hacktricks-skills browser-http-request-smuggling
How to perform browser-powered HTTP request smuggling (client-side desync) attacks. Use this skill whenever the user mentions HTTP request smuggling, browser-based desync, client-side request smuggling, cache poisoning via browser, or wants to abuse browser behavior to create request parsing conflicts. Also trigger for pentesting web applications where you need to bypass front-end controls, poison caches, or leak headers through browser-enqueued requests.
git clone https://github.com/abelrguezr/hacktricks-skills
skills/pentesting-web/http-request-smuggling/browser-http-request-smuggling/SKILL.MDBrowser HTTP Request Smuggling
Browser-powered desync (client-side request smuggling) abuses the victim's browser to enqueue a mis-framed request onto a shared connection so that downstream components parse subsequent requests out-of-sync. Unlike classic front-end/back-end smuggling, payloads are constrained by what a browser can legally send cross-origin.
When to Use This Technique
Use browser HTTP request smuggling when:
- You need to bypass front-end path or method restrictions
- You want to poison caches with malicious content
- You need to leak front-end injected headers (e.g., authentication tokens)
- Classic server-side smuggling isn't available but you have browser access
- You're testing applications with multiple HTTP layers (CDN, WAF, load balancer, origin)
Key Constraints
Browsers enforce strict rules on what they can send. Understand these limitations:
What Browsers CAN Send
- Standard headers via navigation, fetch, or form submission
- Path and query string manipulation
- Form-encoded POST bodies
- Some custom headers via CORS-enabled endpoints
What Browsers CANNOT Send
- Header obfuscation tricks (LWS folding, duplicate TE headers)
- Invalid Content-Length values
- Raw HTTP syntax violations
- Custom headers without CORS preflight approval
Why this matters: You can't use classic smuggling payloads that rely on header manipulation. Instead, focus on path confusion, query injection, and body shaping.
Attack Patterns
1. Path Confusion
Exploit differences in how components parse URL paths:
# Front-end sees: /api/valid # Back-end sees: /api/valid%00/admin # Or: /api/valid/.%2e/admin
When to try: When the application has path-based access controls or when different layers normalize paths differently.
2. Query String Injection
Inject query parameters that affect downstream parsing:
GET /search?q=normal&X-Injected:header=value HTTP/1.1
When to try: When query parameters are reflected or when the back-end treats query strings as part of the request line.
3. Body Shaping via Form POSTs
Use form-encoded data to create ambiguous boundaries:
POST /submit Content-Type: application/x-www-form-urlencoded field=value&X-Injected:header=value
When to try: When the application processes form data and the back-end interprets body content differently.
4. Connection Reuse Attacks
The most powerful browser smuggling technique:
- Identify a high-value request (e.g., authenticated endpoint, admin panel)
- Craft a smuggling payload that will be parsed differently downstream
- Force connection reuse by making both requests to the same origin
- Observe the desync in how the back-end processes the requests
Why reuse matters: Connection-locked behaviors amplify impact. The same TCP connection means the back-end's parser state carries over between requests.
Validation Methods
Distinguish Real Smuggling from Pipelining
False positives are common. Validate genuine desync:
- Test without reuse: Make requests on separate connections. If the effect disappears, it's likely pipelining.
- HTTP/2 nested-response check: In HTTP/2, responses are multiplexed. If you see nested responses, it's not smuggling.
- Timing analysis: Smuggling often shows consistent timing patterns; pipelining is more variable.
Cache Poisoning Validation
If targeting cache poisoning:
- Clear the cache before testing
- Send the smuggling payload
- Request the same URL normally
- Check if the poisoned response is served
Practical Workflow
Step 1: Reconnaissance
- Map the application's HTTP layers (CDN, WAF, load balancer, origin)
- Identify endpoints that reflect user input
- Find endpoints that cache responses
- Look for path-based or method-based access controls
Step 2: Identify Attack Surface
- Which endpoints can you access via browser?
- What headers does the browser send automatically?
- Are there CORS-enabled endpoints for custom headers?
- What form submissions are available?
Step 3: Craft the Payload
Based on constraints:
- Use only browser-legal syntax
- Focus on path/query/body manipulation
- Design for connection reuse with high-value requests
Step 4: Test and Validate
- Test on separate connections first (baseline)
- Test with connection reuse
- Validate the desync effect
- Rule out pipelining artifacts
Step 5: Exploit
- Poison caches with malicious content
- Bypass access controls
- Leak sensitive headers
- Chain with other vulnerabilities
Common Targets
- CDN-origin desync: CDN caches one response, origin processes differently
- WAF bypass: WAF sees clean request, back-end sees malicious
- Load balancer confusion: LB routes based on different parsing than origin
- API gateway attacks: Gateway and backend interpret requests differently
Limitations and Mitigations
Browser Limitations
- Cannot send arbitrary headers without CORS
- Cannot use header obfuscation
- Limited to standard HTTP methods and syntax
Detection Evasion
- Use legitimate-looking paths and parameters
- Avoid obvious attack patterns
- Blend with normal traffic timing
Defenses
- Consistent HTTP parsing across all layers
- Strict input validation
- Cache invalidation controls
- Connection management policies
References
- PortSwigger Research – Browser-Powered Desync Attacks
- PortSwigger Academy – Client-Side Desync
- Distinguishing Pipelining vs Smuggling
Quick Checklist
Before attempting browser HTTP request smuggling:
- Can I access the target via browser?
- Are there multiple HTTP layers in the request path?
- Do I have a high-value request to reuse the connection with?
- Can I craft a payload using only browser-legal syntax?
- Have I validated this isn't just pipelining?
- Do I have a clear exploitation goal (cache poisoning, bypass, leak)?