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.

install
source · Clone the upstream repo
git clone https://github.com/abelrguezr/hacktricks-skills
manifest: skills/pentesting-web/http-request-smuggling/browser-http-request-smuggling/SKILL.MD
source content

Browser 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:

  1. Identify a high-value request (e.g., authenticated endpoint, admin panel)
  2. Craft a smuggling payload that will be parsed differently downstream
  3. Force connection reuse by making both requests to the same origin
  4. 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:

  1. Test without reuse: Make requests on separate connections. If the effect disappears, it's likely pipelining.
  2. HTTP/2 nested-response check: In HTTP/2, responses are multiplexed. If you see nested responses, it's not smuggling.
  3. Timing analysis: Smuggling often shows consistent timing patterns; pipelining is more variable.

Cache Poisoning Validation

If targeting cache poisoning:

  1. Clear the cache before testing
  2. Send the smuggling payload
  3. Request the same URL normally
  4. 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

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)?