flawopen.com/Teardowns/cve-2026-71416-headroom-websocket-origin-hijacking
CVE-2026-71416: Pembajakan Origin WebSocket pada Headroom
Headroom tidak memeriksa Origin WebSocket; situs yang dibuka dapat meneruskan permintaan LLM melalui proksi. Perbarui ke 0.35.0+.
Petugas resepsionis membiarkan siapa pun masuk ke loket privat karena tidak memeriksa kartu pengunjung. Origin adalah kartu itu: proksi harus memeriksanya sebelum membuka saluran yang dapat memakai kunci API tersimpan.
Konsep Kunci & Istilah
WebSocket- Koneksi dua arah yang bertahan lama, dimulai dengan permintaan HTTP Upgrade dan membawa pesan ke kedua arah.
Header Origin- Skema, host, dan port halaman yang dikirim browser untuk menunjukkan asal permintaan. Pada handshake WebSocket, server harus menerapkan kebijakan kepercayaannya sendiri; header CORS tidak menggantikan pemeriksaan ini.
CSWSH- Cross-Site WebSocket Hijacking: halaman tak tepercaya membuka WebSocket ke layanan yang dapat dijangkau, tetapi layanan tidak memverifikasi asal peminta.
Kredensial ambient- Rahasia yang sudah tersedia bagi proses, seperti kunci API dalam variabel lingkungan, yang dapat mengautentikasi permintaan tanpa kredensial dari klien.
CWE-1385- Origin tidak divalidasi pada WebSocket: endpoint tidak memeriksa apakah asal komunikasi diizinkan.
Pemetaan kerangka kerja
- Referensi CWE untuk kelemahan yang dijelaskan dalam panduan ini: CWE-1385
- OWASP GenAI 2025 — LLM06:2025 Agensi berlebihan
Analisis Akar Masalah (Root Cause)
Handler WebSocket /v1/responses milik Headroom menerima koneksi browser sebelum memeriksa Origin pada handshake. Setelah itu, proksi dapat menambahkan OPENAI_API_KEY dari lingkungannya sendiri ke permintaan upstream. Kebijakan same-origin browser tidak dengan sendirinya mencegah JavaScript memulai WebSocket ke host lain yang dapat dijangkau; browser biasanya mengirim Origin, dan server harus menolak asal di luar kebijakannya. Karena itu, eksploitasi mensyaratkan browser korban dapat menjangkau proksi Headroom yang rentan dan proksi memiliki kredensial atau integrasi yang berguna. Advisory menyatakan koneksi yang diterima dapat mengirim permintaan LLM arbitrer. Eksekusi perintah di host bergantung pada apakah permintaan dapat memakai alat yang dikonfigurasi untuk menjalankan perintah; hal itu bukan akibat otomatis dari pemeriksaan header yang hilang. CNA menyebut versi sebelum 0.35.0 terdampak, sedangkan metadata paket pada advisory GitHub menyebut 0.23.0. Perbarui ke 0.35.0 atau lebih baru dan verifikasi versi terpasang.
Alur Serangan Langkah demi Langkah
Proksi memiliki kewenangan upstream
Proses Headroom dapat menyimpan kunci OpenAI dalam OPENAI_API_KEY; klien browser tidak perlu mengirim kunci tersebut.
Browser membuka halaman tak tepercaya
Jika browser dapat menjangkau endpoint WebSocket Headroom, skrip halaman dapat mencoba terhubung. Browser menyertakan Origin halaman pada handshake.
Handler rentan menerima tanpa kebijakan Origin
Pada handler terdampak, permintaan mencapai websocket.accept() tanpa lebih dahulu menolak Origin tak tepercaya. Kebijakan same-origin bukan pemeriksaan otorisasi WebSocket di server.
Proksi meneruskan permintaan terautentikasi
Headroom dapat mengisi header Authorization upstream yang kosong dari lingkungan. Halaman yang dikendalikan penyerang lalu dapat memicu permintaan dengan kewenangan upstream proksi; dampaknya bergantung pada alat, kredensial, jangkauan jaringan, dan interaksi pengguna.
Perbaikan menolak Origin terlarang sebelum routing
Patch upstream memeriksa Origin sebelum menerima dan meneruskan sesi. Origin browser secara default dibatasi ke loopback, Origin tertentu dapat dikonfigurasi, dan koneksi terlarang ditutup dengan kode 1008.
Kode Sumber: Rentan vs Aman
Advisory menunjuk handle_openai_responses_ws() dan pemeriksaan yang hilang sebelum websocket.accept(). Commit upstream c632023 menambahkan _is_allowed_websocket_origin() dan menolak Origin yang tidak diizinkan sebelum routing. Klien native tanpa Origin tetap didukung, Origin browser default-nya loopback, dan Origin eksplisit dapat diatur melalui HEADROOM_WS_ORIGINS atau HEADROOM_CORS_ORIGINS. Cuplikan ringkas ini menampilkan batas kepercayaan yang berubah; fungsi bantu tidak ditampilkan seluruhnya. Tes regresi upstream mencakup Origin kosong, loopback, remote, malformed, dan konfigurasi eksplisit.
Cuplikan sumber: headroom/proxy/handlers/openai.py
async def handle_openai_responses_ws(self, websocket: WebSocket) -> None:
# Pola rentan: terima sesi browser sebelum memvalidasi origin.
await websocket.accept()
await self._relay_responses_session(websocket)
async def handle_openai_responses_ws(self, websocket: WebSocket) -> None:
ws_headers = dict(websocket.headers)
if not _is_allowed_websocket_origin(ws_headers):
logger.warning(
"event=websocket_origin_not_allowed origin=%r",
_header_get(ws_headers, "origin"),
)
await websocket.close(code=1008, reason="origin not allowed")
return
# Hanya sesi browser yang disetujui kebijakan yang mencapai perutean upstream.
await websocket.accept()
await self._relay_responses_session(websocket)
Daftar Periksa Penguatan Sistem Rekayasa
- ✓Perbarui Headroom ke 0.35.0 atau lebih baru; inventarisasi versi paket dan image deployment yang terpasang, bukan hanya file dependensi.
- ✓Validasi WebSocket
Originsebelum memanggilaccept()atau meneruskan pesan upstream; tolak Origin non-loopback kecuali secara eksplisit diizinkan. - ✓Pertahankan klien native tanpa
Originhanya jika jenis klien diverifikasi secara terpisah; Origin browser yang tidak ada bukan otorisasi. - ✓Jangan gunakan
*pada konfigurasi Origin proksi yang memiliki kredensial; daftarkan Origin tepercaya secara tepat dan uji normalisasi port default. - ✓Jika memungkinkan, ikat proksi pengembangan lokal ke loopback; jika host lain dapat menjangkaunya, wajibkan autentikasi atau kontrol jaringan.
- ✓Gunakan kunci upstream dengan cakupan dan masa berlaku terbatas jika tersedia; jangan paparkan shell atau alat berdampak tinggi ke permintaan yang melintasi batas browser.
- ✓Tambahkan tes regresi bahwa Origin remote ditutup dengan pelanggaran kebijakan sebelum routing upstream, sambil memastikan loopback, Origin konfigurasi, dan klien native yang disetujui tetap berfungsi.
- ✓Anggap eksekusi perintah bergantung pada kemampuan alat yang dikonfigurasi; cacat Origin bukan otomatis RCE pada host.