Kembali

2026/10/26

HTTP2Shell (CVE-2026-111497): memperbarui biner tidak menambal proses yang sedang berjalan

Celah Brotli di balik HTTP2Shell menjangkau Node.js, Bun, dan Python. Cara menemukan eksposur nyata di proses aktif dan me-restart agen AI dengan aman.

Pada 21 Oktober 2026, Node.js merilis perbaikan untuk CVE-2026-111497, sebuah celah out-of-bounds write pada dekoder Brotli milik Google. Dalam beberapa hari, menyusul advisori untuk Bun, paket Python brotli dan brotlicffi, Envoy, serta Istio, dan media keamanan menamai celah ini Node2Shell, lalu HTTP2Shell. Terlepas dari julukannya, ini bukan bug pada protokol HTTP/2. Ini adalah bug dekompresi, dan relevan di mana pun perangkat lunak mendekode data Brotli yang dapat dipengaruhi penyerang.

Artikel ini menjelaskan apa yang sudah terverifikasi, apa yang baru sebatas kemungkinan, dan cara memeriksa sistem Anda sendiri. Artikel ini juga membahas pelajaran dari penanganan kami sendiri: memasang biner yang sudah diperbaiki tidak memperbaiki proses yang masih menjalankan versi lama. Di lingkungan kami, sesi Claude Code yang berjalan lama tetap memakai runtime tertanam versi lama setelah Claude Code yang terpasang diperbarui.

Poin-poin penting

  • Terdampak: Brotli upstream 1.0.3 hingga 1.2.0. Diperbaiki: 1.0.10, 1.1.1, dan 1.2.1. Produk yang membundel Brotli memerlukan rilis perbaikannya sendiri.
  • Eksposur memerlukan jalur nyata: data Brotli yang dapat dipengaruhi penyerang mencapai dekoder yang rentan. Nama produk atau akses jaringan saja bukan bukti.
  • Periksa proses yang sedang berjalan, bukan hanya paket yang terpasang. Sebuah proses tetap memakai runtime yang dimuat saat ia dijalankan sampai di-restart.
  • Restart agen AI yang menyimpan state satu per satu, setelah event, persetujuan, dan state pekerjaannya diserahterimakan terlebih dahulu.

1. Apa kerentanannya

Saat dekoder menemui block switch yang tidak valid, ia melaporkan “butuh input tambahan”, bukan error format permanen. Pemanggil berbasis streaming lalu terus memasukkan byte, dan dekoder menambahkannya ke buffer internal berukuran delapan byte sehingga menulis melewati batas akhirnya. Advisori Node.js menyatakan bahwa penyerang yang dapat menyuplai data Brotli yang didekompresi aplikasi dengan node:zlib “dapat merusak memori proses, yang dapat menyebabkan crash, kebocoran memori proses, atau eksekusi kode jarak jauh”.

Tingkat keparahan berbeda menurut sumber. Node.js menilainya High. Advisori GitHub untuk paket Python dan advisori Envoy menilainya Critical, dengan skor CVSS 4.0 sebesar 9.2. Ubuntu saat ini mencantumkannya sebagai prioritas Medium. Per 26 Oktober, penilaian CISA pada catatan CVE mencantumkan eksploitasi sebagai “none”, dan CVE ini tidak masuk katalog Known Exploited Vulnerabilities milik CISA. Advisori Node.js tetap menyebut eksekusi kode jarak jauh sebagai dampak yang mungkin terjadi, jadi jangan jadikan belum adanya laporan serangan sebagai alasan untuk menunggu.

2. Prasyarat: kapan Anda benar-benar terekspos

Ketiga kondisi berikut harus terpenuhi:

  1. Dekoder yang rentan dimuat di dalam proses: pustaka Brotli bawaan atau milik sistem dalam rentang versi terdampak tanpa perbaikan atau backport.
  2. Ada yang memanggilnya: dekompresi eksplisit, atau dekode otomatis Content-Encoding: br.
  3. Input dapat dipengaruhi penyerang: respons dari URL sembarang, file yang diunggah, body permintaan masuk, atau lalu lintas HTTP tanpa enkripsi di jaringan yang tidak bersahabat.

Dekode otomatis adalah jalur yang paling sering terlewat oleh tim. Advisori Bun mencatat bahwa fetch secara default mengirim Accept-Encoding: br dan mendekode responsnya, sehingga setiap program Bun yang mengambil URL tidak tepercaya memiliki jalur ini. Di Python, begitu brotli atau brotlicffi terpasang, urllib3 otomatis mendekode respons Content-Encoding: br, dan requests juga mengiklankan br dalam permintaannya. Hal ini terjadi bahkan ketika kode Anda sendiri sama sekali tidak menyebut Brotli. Envoy dan Istio hanya terekspos jika dekompresor Brotli dikonfigurasi.

3. Terkonfirmasi terdampak versus sekadar mungkin

Status per 26 Oktober 2026. Periksa advisori yang ditautkan, karena situasinya berkembang cepat.

KomponenStatusDiperbaiki di
Brotli upstream (C)Terkonfirmasi: 1.0.3 hingga 1.2.01.0.10, 1.1.1, 1.2.1
Node.js 22, 24, 26Terkonfirmasi22.23.4, 24.22.1, 26.12.1
Node.js 20 dan yang lebih lama (end of life)Tidak dinilai; Node.js menganggap lini end-of-life selalu terdampakPindah ke lini yang masih didukung
Bun (termasuk executable hasil kompilasi)Terkonfirmasi: 1.0.21 hingga 1.4.31.4.4, dan build ulang aplikasi hasil kompilasi
Python brotli / brotlicffiTerkonfirmasi: mulai 1.0.31.2.1 / 1.2.1.0
Envoy (dekompresor Brotli dikonfigurasi)Terkonfirmasi1.40.0, 1.39.3, 1.38.6, 1.37.8 (1.36.12 pada cabang 1.36 yang tidak lagi didukung)
Istio (dekompresi Brotli diaktifkan)Terkonfirmasi1.31.2, 1.30.6, 1.29.9 (rilis terakhir 1.29)
Paket brotli UbuntuPerlu evaluasi (semua rilis)Belum ada paket perbaikan
Paket nodejs UbuntuRentan di 20.04 (Brotli bawaan). Pada 22.04 dan yang lebih baru memakai Brotli sistem, sehingga mengikuti baris di atasLihat tracker Ubuntu
Paket brotli DebianDiperbaiki di bookworm dan trixie; forky belum1.0.9-2+deb12u1, 1.1.0-2+deb13u1
Chrome, Electron, dan aplikasi ElectronBelum diketahui: tidak ditemukan pernyataan vendorPantau catatan rilis vendor

Tentang baris terakhir: Chrome dan Electron menyertakan salinan Brotli sendiri, dan aplikasi Electron juga menanamkan runtime Node.js. Saat artikel ini ditulis, rilis stabil Electron terbaru (45.0.0, 44.9.3, dan 43.8.3, semuanya 21 Oktober) mencantumkan Node.js 24.22.0, bukan 24.22.1, dan catatan rilisnya tidak menyebut CVE ini. Pra-rilis Electron sejak 23 Oktober sudah membawa Node.js 24.22.1, sehingga perbaikan di rilis stabil tampaknya akan datang, tetapi belum dirilis. Artinya, aplikasi desktop berbasis Electron mungkin terekspos, bukan terkonfirmasi rentan. Hal yang sama berlaku untuk aplikasi chat dan alat AI desktop: periksa pernyataan masing-masing vendor sebelum menyebutnya terdampak atau aman.

Satu jebakan lagi: versi pustaka yang dilaporkan tidak membuktikan apa pun, ke arah mana pun. Node.js 22.23.4 yang sudah diperbaiki tetap melaporkan process.versions.brotli sebagai 1.1.0, karena perbaikannya di-backport. Distribusi pun melakukan hal yang sama. Nilailah berdasarkan versi perbaikan produk atau status keamanan distribusi, bukan dari string versi Brotli.

4. Temuan di lingkungan kami sendiri

Kami melakukan inventarisasi read-only sebelum mengubah apa pun. Berikut yang kami amati, sudah dianonimkan, dengan temuan terkonfirmasi dipisahkan dari risiko yang tidak dapat kami verifikasi.

Pengamatan terkonfirmasi

  • Claude Code yang terpasang sudah diperbarui, tetapi sekitar selusin sesi yang berjalan lama masih menjalankan build lama yang dimulai beberapa minggu sebelumnya. Sesi-sesi itu tidak pernah di-restart.
  • Hitungan pertama kami melewatkan tiga di antaranya. Sesi-sesi itu berjalan di bawah proses helper yang berbeda, sehingga pencarian berdasarkan command line tidak cocok. Pencarian berdasarkan executable berhasil menemukannya.
  • File build lama sudah dihapus dari disk oleh updater, sehingga versi Bun tertanam pada proses-proses itu tidak dapat dibaca.
  • Sisa instalasi lewat package manager dari build Claude Code yang lebih lama menanamkan Bun 1.4.0. Tidak ada yang memakainya dalam operasi normal, tetapi jalur fallback bisa saja memakainya. Kami menghapusnya setelah membuktikan tidak ada yang bergantung padanya.
  • Runtime Node.js end-of-life yang tidak terpakai masih terpasang di sebuah server. Kami menghapusnya dengan cara yang sama.
  • Build Claude Code terbaru yang kami pakai setelah upgrade (2.1.310) berisi Bun 1.4.4. Kami mengonfirmasinya dengan memeriksa binernya. Changelog Anthropic tidak menyebut CVE ini, jadi periksa build Anda sendiri dengan cara yang sama.

Belum terverifikasi, diperlakukan sebagai risiko

  • Apakah sesi-sesi lama itu benar-benar rentan. Versi Bun-nya tidak dapat dibaca. Bun 1.4.4 yang sudah diperbaiki baru muncul sekitar 22 Oktober, setelah build tersebut, sehingga kami menganggapnya terdampak.
  • Apakah penyerang dapat mencapai dekoder melalui sesi-sesi itu, misalnya dengan membuat sesi mengambil URL berbahaya. Jalur ini masuk akal berdasarkan perilaku fetch yang didokumentasikan Bun, tetapi kami tidak membuktikannya.
  • Apakah perangkat lunak lain yang membundel salinan Brotli sendiri ikut terdampak. Jika tidak ada pernyataan vendor, kami memantau produk tersebut terhadap rilis vendornya, alih-alih mengasumsikan aman atau rentan.

Kami tidak menemukan bukti eksploitasi. Kami juga tidak menganggap itu sebagai bukti keamanan: solusinya adalah menghilangkan eksposur, bukan mencari argumen untuk mengabaikannya.

5. Daftar periksa deteksi dan remediasi

Temukan dependensinya

Cari Brotli di tempat ia dibundel, bukan hanya di tempat ia terpasang sebagai paket. Periksa SBOM dan image container Anda untuk Node.js, Bun, paket Python, Envoy, dan Brotli yang di-link secara statis. Periksa juga dependensi transitif Python, karena Brotli sering ikut terpasang sebagai extra opsional.

# Node.js: compare with 22.23.4 / 24.22.1 / 26.12.1
node -p process.version
# Python packages: run once per interpreter and virtual environment
python -m pip list 2>/dev/null | grep -iE '^(brotli|brotlicffi) '
pipdeptree -r -p brotli          # what pulled it in
# Debian / Ubuntu system library (then check the distro tracker)
dpkg-query -W -f='${db:Status-Abbrev} ${Package} ${Version}\n' 'libbrotli*'
# Container images, with an SBOM scanner such as Syft
syft <image> | grep -iE 'brotli|node|bun'

Temukan runtime tertanam

Program yang di-build dengan bun build --compile membawa salinan Bun sendiri. Advisori Bun menyatakan program tersebut tetap terdampak sampai di-build ulang dengan 1.4.4. Meng-upgrade Bun di mesin build tidak mengubah biner yang sudah di-deploy.

# The Bun version inside a compiled executable
grep -aoE 'Bun v1\.[0-9]+\.[0-9]+' /path/to/binary | sort -u

Temukan proses yang sedang berjalan

Periksa apa yang sedang berjalan, bukan apa yang terpasang. Di Linux, proses yang executable-nya telah diganti atau dihapus akan menampilkan (deleted). Itu tanda kuat bahwa proses tersebut masih menjalankan build lama.

# Processes still running a deleted (replaced) executable (run as root to see all users)
for p in /proc/[0-9]*; do
  e=$(readlink "$p/exe" 2>/dev/null) || continue
  case "$e" in *"(deleted)") echo "${p#/proc/} $e";; esac
done
# Processes older than the fix
pgrep -af 'node|bun|claude'      # then: ps -o pid,lstart,args -p <pid>

Di macOS, lsof -p <pid> menampilkan executable yang dimuat sebuah proses. Cocokkan berdasarkan executable, bukan nama proses, atau Anda akan melewatkan proses helper dan worker latar belakang.

Perbaiki, build ulang, deploy ulang

  • Upgrade ke versi perbaikan di tabel. Gunakan paket yang sudah ditambal dari distribusi Anda jika tersedia backport.
  • Build ulang image container dan executable hasil kompilasi, lalu deploy ulang. Base image yang sudah ditambal tidak berpengaruh apa pun pada image yang belum Anda build ulang.
  • Hapus runtime yang tidak terpakai dan sisa instalasi, setelah membuktikan tidak ada layanan, job, atau skrip yang bergantung padanya. Siapkan rollback.
  • Jika perbaikan belum tersedia, nonaktifkan dekode Brotli untuk input tidak tepercaya di tempat yang aman untuk melakukannya. Untuk Bun, fetch(url, { decompress: false }) berlaku per permintaan. Tetapkan penanggung jawab dan tanggal berakhir untuk setiap mitigasi.

Restart dan verifikasi

Setelah restart, periksa executable dan versi runtime aktual dari proses baru. Lalu periksa hasil bisnisnya: antrean sudah habis diproses, job terjadwal berhasil, dan peringatan monitoring tetap masuk. Perintah upgrade yang berhasil hanya membuktikan bahwa perintah itu telah dijalankan.

6. Me-restart agen AI persisten dengan aman

Agen AI yang berjalan lama menyimpan state: pemanggilan tool yang tertunda, persetujuan, pesan dalam antrean, dan klaim atas pekerjaan. Me-restart semuanya sekaligus dapat menghilangkan state tersebut. Urutan berikut berhasil bagi kami:

  1. Inventarisasi setiap sesi: versi executable, status (idle, menunggu, atau sibuk), aktivitas terakhir, pekerjaan tertunda, persetujuan yang sedang ditunggu atau dipegangnya, event yang belum di-acknowledge, dan bagaimana semuanya akan dipulihkan.
  2. Pindahkan persetujuan keluar dari memori. Persetujuan yang hanya ada di percakapan sebuah sesi akan hilang saat restart. Sebelum restart, catat setiap persetujuan yang tertunda (apa yang disetujui, oleh siapa, untuk perubahan spesifik yang mana) di tempat yang persisten, seperti tiket atau pull request. Setelahnya, pastikan sesi masih melihatnya. Jika ragu, mintalah persetujuan ulang alih-alih berasumsi.
  3. Buktikan penggantinya terlebih dahulu. Pastikan sesi pada build yang sudah diperbaiki sudah berfungsi, dan bahwa event watcher yang independen dari sesi lama sedang berjalan, sehingga tidak ada event yang bergantung pada sesi yang sedang di-restart.
  4. Restart sesi yang idle lebih dulu, satu per satu. Setelah masing-masing, verifikasi bahwa proses lama sudah hilang, proses baru menjalankan executable yang sudah diperbaiki, riwayat percakapan utuh, dan koneksi jarak jauh sudah tersambung kembali. Baru kemudian lanjut ke sesi berikutnya.
  5. Restart pemilik tersibuk paling akhir, di sela-sela tugas. Minta ia menulis catatan serah terima, hentikan watcher-nya hanya ketika pekerjaan tertunda dan event yang belum di-acknowledge sama-sama nol, restart, lalu pastikan watcher-nya melanjutkan dari posisi yang tersimpan tanpa ada yang terlewat.
  6. Antisipasi input yang mengantre saat tersambung kembali. Salah satu sesi yang kami restart menerima pesan yang sudah menunggu selama sepuluh hari dan langsung menindaklanjutinya. Periksa inbox setiap sesi sebelum restart, dan beri tahu pemiliknya.
  7. Berhenti dan eskalasikan jika ada langkah yang tidak dapat menunjukkan bahwa pekerjaan berhasil dipulihkan. Jangan beralih ke mematikan semuanya.

Tetapkan definisi “selesai” sebelum memulai. Selesai berarti tidak ada proses yang berjalan pada build terdampak, setiap pengecualian terdokumentasi dengan penanggung jawab dan tanggal pemeriksaan ulang, dan pemeriksaan bisnis lolos. “Paketnya sudah di-upgrade” belum berarti selesai.

Sumber