Reverse proxy menerima request HTTP/1.1, menentukan tempat body berakhir, lalu meneruskan trafik ke application server melalui koneksi persisten. Jika application server menentukan batas berbeda dari informasi framing yang sama, kedua komponen berhenti sepakat mengenai byte mana yang termasuk ke request tertentu. Byte yang dianggap sebagai body oleh satu komponen dapat menjadi awal request baru bagi komponen lain.

Perbedaan tersebut merupakan kondisi inti HTTP request smuggling. Masalahnya bukan sekadar header malformed, proxy, atau connection reuse secara terpisah. Masalahnya adalah parser differential di sepanjang chain tempat beberapa recipient menafsirkan framing request dan setidaknya satu koneksi membawa trafik berikutnya.

Dampak keamanannya berasal dari desinkronisasi. Setelah front end dan back end berada pada posisi berbeda dalam byte stream, suffix yang dikendalikan penyerang dapat memengaruhi konteks parsing request berikutnya. Authentication, routing, cache policy, dan kontrol lain kemudian dapat bekerja pada urutan request yang berbeda dari urutan yang dilihat service downstream.

Framing adalah batas keamanan antar-pemroses HTTP

HTTP/1.1 dibawa sebagai rangkaian pesan di atas byte stream. Recipient harus menentukan akhir satu pesan sebelum dapat mem-parse pesan berikutnya dengan aman. Untuk request yang memiliki content, Content-Length atau Transfer-Encoding menyediakan informasi framing. RFC 9112 mendefinisikan precedence dan penanganan error agar recipient yang sesuai dapat mencapai batas yang sama.

Content-Length yang valid tanpa Transfer-Encoding memberikan panjang body dalam octet. Dengan chunked transfer coding, sintaks chunk menandai batas body. Sender tidak boleh mengirim Content-Length pada pesan yang juga memiliki Transfer-Encoding.

Trafik yang diterima tetap dapat melanggar persyaratan sender tersebut. RFC 9112 mengizinkan server menolak request yang membawa kedua field atau memprosesnya berdasarkan Transfer-Encoding; setelah merespons, server harus menutup koneksi. Intermediary yang meneruskan pesan seperti itu memiliki kewajiban tambahan, termasuk menghapus Content-Length yang diterima sebelum forwarding setelah memproses transfer coding.

Aturan ini relevan bagi keamanan karena ambiguitas yang diteruskan dapat mencapai parser kedua. Jika dua recipient menerapkan aturan framing berbeda, perbedaannya tidak lagi terbatas pada validasi satu request malformed. Perbedaan itu mengubah lokasi awal request berikutnya.

Parser differential menjadi stream differential

Pertimbangkan front end yang menerima request dengan sinyal framing yang bertentangan. Misalkan front end memutuskan bahwa body mencakup sejumlah byte berdasarkan satu aturan, sedangkan back end menganggap request berakhir pada posisi byte yang lebih awal.

Byte di antara kedua posisi itu kini memiliki peran berbeda. Bagi front end, byte tersebut masih bagian dari request pertama. Bagi back end, byte itu tersedia untuk di-parse sebagai request lain.

Kondisi ini sering disebut dengan label seperti CL.TE atau TE.CL, yang merujuk pada perbedaan terkait Content-Length dan Transfer-Encoding. Label tersebut berguna sebagai singkatan, tetapi dapat menyembunyikan mekanisme yang lebih umum. Differential juga dapat muncul dari penanganan yang tidak konsisten terhadap sintaks field malformed, field duplikat, sintaks transfer coding, line termination, atau normalisasi oleh intermediary.

RFC 9112 secara eksplisit memperingatkan bahwa parsing yang longgar dapat menimbulkan risiko request smuggling ketika beberapa recipient menafsirkan robustness secara berbeda. Parser yang menerima sintaks tidak biasa belum tentu dapat dieksploitasi sendirian. Kondisi berbahaya muncul ketika parser lain pada jalur yang sama memberi semantik berbeda pada byte yang diterima.

Normalisasi dapat memindahkan, bukan menghilangkan, ambiguitas

Reverse proxy sering mentransformasi request. Proxy dapat mendekode transfer coding, menggabungkan field line, menulis ulang target, menghapus hop-by-hop field, atau menerjemahkan antarversi HTTP. Transformasi merupakan perilaku normal intermediary, tetapi juga berarti pesan yang diterima back end mungkin tidak identik byte demi byte dengan pesan client.

Keamanan karena itu bergantung pada seluruh transisi:

byte client
    |
parse front end
    |
representasi request yang dinormalisasi
    |
serialisasi atau translasi protokol
    |
parse back end

Menolak string mencurigakan yang sudah dikenal di edge lebih lemah daripada memastikan setiap request yang diterima memiliki satu interpretasi framing yang tidak ambigu setelah transformasi. Front end dapat menerima varian sintaks, hanya menormalisasi sebagian, lalu menghasilkan bentuk yang di-parse berbeda oleh komponen downstream.

Karena itu sanitasi header generik bukan kontrol lengkap. Persoalannya adalah struktur pesan, bukan hanya keberadaan nama field. Front end harus menolak framing ambigu atau menghasilkan pesan downstream yang framing-nya mengikuti aturan protokol target tanpa mempertahankan sinyal yang bertentangan.

Koneksi back end persisten memperbesar konsekuensi

Perbedaan framing memerlukan konteks parsing berikutnya agar menjadi masalah lintas-request. Koneksi persisten menyediakan konteks tersebut secara alami.

Banyak proxy mempertahankan pool koneksi ke service back end. Request dari koneksi client berbeda dapat diserialisasi ke koneksi upstream yang digunakan ulang sesuai model pooling proxy. Jika penyerang meninggalkan byte yang ditafsirkan back end sebagai awal request lain, trafik berikutnya pada koneksi itu dapat di-parse relatif terhadap state yang dipengaruhi penyerang.

Konsekuensi persisnya bergantung pada arsitektur. Koneksi upstream khusus untuk satu client memiliki paparan berbeda dari shared pool. Komponen yang menutup koneksi setelah framing error menghapus sisa stream yang dapat membawa mismatch ke depan. Protocol gateway yang mem-parse penuh dan merekonstruksi pesan dapat menghilangkan sebagian kelas ambiguitas sambil menambahkan batas translasi sendiri.

Connection reuse karena itu merupakan penguat, bukan akar masalah. Menonaktifkan reuse dapat mengurangi jalur eksploitasi tertentu, tetapi tidak membuat parser yang tidak konsisten menjadi ekuivalen atau mengubah framing malformed menjadi trafik valid.

HTTP/2 mengubah framing tetapi tidak menghapus risiko translasi

HTTP/2 tidak membatasi body request dengan chunked transfer coding HTTP/1.1. Frame membawa panjang eksplisit dan stream menyediakan struktur pesan pada level protokol. Field content-length tetap dapat muncul, tetapi RFC 9113 menganggap pesan malformed ketika nilainya tidak sama dengan total payload DATA frame untuk pesan yang memiliki content.

Desain tersebut menghilangkan beberapa ambiguitas text framing HTTP/1.1 pada jalur HTTP/2 murni. Namun deployment nyata sering mengakhiri HTTP/2 di edge lalu berkomunikasi dengan origin melalui HTTP/1.1. Edge kemudian melakukan translasi protokol.

Batas keamanan berpindah ke translasi itu. Intermediary harus memetakan request HTTP/2 yang sudah ter-frame menjadi request HTTP/1.1 yang valid dan tidak ambigu. Ia tidak boleh menghasilkan kombinasi downstream yang batas body-nya dapat ditafsirkan berbeda oleh origin.

Karena itu koneksi eksternal yang memakai HTTP/2 tidak membuktikan seluruh jalur request bebas dari perilaku framing HTTP/1.1. Protokol yang menghadap origin dan logika konversi gateway tetap menjadi bagian attack surface.

Penolakan ketat lebih aman daripada toleransi parser pada batas chain

Fitur robustness secara historis memungkinkan implementasi HTTP menerima sintaks di luar grammar ketat. Dalam kondisi satu recipient, toleransi dapat terlihat tidak berbahaya karena parser mencapai satu representasi internal dan melanjutkan proses.

Intermediary berbeda: ia sekaligus recipient dan sender. Menerima bentuk nonkanonis menimbulkan tanggung jawab untuk memastikan forwarding tidak membuka interpretasi kedua.

RFC 9112 mewajibkan framing Content-Length yang tidak valid diperlakukan sebagai unrecoverable error, kecuali kasus sempit berupa daftar comma-separated dengan semua nilai valid dan identik. RFC tersebut juga menentukan penanganan pesan yang membawa Transfer-Encoding dan Content-Length, termasuk penutupan koneksi setelah pemrosesan server.

Persyaratan ini membatasi ambiguitas berbahaya pada batas protokol. Implementasi yang membuat aturan recovery permisif sendiri berisiko menciptakan parser differential dengan peer yang memakai strategi recovery berbeda.

Strictness paling bernilai pada titik ketika trafik berpindah antarimplementasi. Request yang ditolak tidak memiliki interpretasi framing downstream. Request ambigu yang diterima memilikinya.

Filtering di edge tidak dapat menggantikan kesepakatan downstream

Web application firewall atau reverse proxy dapat memeriksa request sebelum meneruskannya. Kontrol tersebut mengasumsikan perangkat keamanan dan service yang dilindungi mengevaluasi request logis yang sama.

Desinkronisasi mematahkan asumsi itu. Edge dapat menerapkan policy pada satu batas request sementara back end menerapkan semantik aplikasi pada batas lain. Fragmen request downstream kemudian dapat berada dalam konteks yang tidak pernah dievaluasi sebagai request independen oleh front end.

Hal ini tidak berarti setiap parser differential melewati semua kontrol. Eksploitasi bergantung pada perilaku parsing, manajemen koneksi, routing, dan byte yang diterima masing-masing komponen. Poin arsitekturalnya lebih sempit: policy enforcement tidak dapat mencakup urutan pesan secara andal jika enforcement dan execution tidak sepakat mengenai batas pesan.

Prinsip yang sama berlaku untuk logging. Access log front end dapat mencatat request yang dikenali proxy, sementara log origin mencatat urutan berbeda. Dalam investigasi, mismatch tersebut merupakan bukti masalah batas, bukan bukti bahwa salah satu sumber log rusak.

Kompatibilitas parser harus diuji sebagai pasangan

Meninjau proxy dan origin secara terpisah dapat melewatkan properti yang relevan. Setiap komponen mungkin memiliki perilaku terdokumentasi yang terlihat masuk akal sendiri, tetapi komposisinya tetap dapat tidak aman jika bahasa yang mereka terima berbeda pada edge yang sensitif terhadap framing.

Perbandingan penting mencakup versi dan konfigurasi persis di produksi: penanganan duplicate length field, nilai decimal invalid, daftar transfer coding, whitespace, line termination, sintaks obsolete, penutupan koneksi, normalisasi, dan konversi protokol.

Pengujian juga harus mempertahankan jalur jaringan aktual. Mengirim request crafted langsung ke origin melewati pasangan parser. Mengirim hanya melalui front end tanpa mengamati perilaku downstream dapat menyembunyikan differential yang tidak diekspos edge pada responsnya.

Hardening produksi sering berasal dari pengurangan pilihan interpretasi: tolak framing malformed lebih awal, jangan teruskan sinyal panjang yang bertentangan, normalisasi sesuai protokol outbound, perbarui implementasi intermediary dan origin, serta perlakukan perbedaan jumlah request front end/back end yang tidak dapat dijelaskan sebagai sinyal masalah batas protokol.

Batas pesan adalah bagian dari konteks authorization

Request smuggling sering dikategorikan sebagai cacat parsing HTTP, tetapi dampak operasionalnya mencapai layer yang lebih tinggi. Keputusan authentication dan authorization melekat pada request hanya setelah komponen menentukan byte mana yang membentuk setiap request.

Jika edge mengautentikasi request A sementara origin mem-parse sebagian byte dari A sebagai request B, sistem tidak lagi memiliki unit bersama tempat policy dapat diterapkan. Routing, caching, rate limit, header injection, dan identity propagation dapat dievaluasi terhadap unit yang berbeda.

Konsistensi framing karena itu merupakan prasyarat bagi kontrol layer atas, bukan detail implementasi tingkat rendah. Chain request yang aman bukan chain dengan parser paling toleran, melainkan chain tempat setiap pesan yang diterima melintasi setiap batas protokol dengan satu interpretasi yang stabil dan dapat ditegakkan.