CVE-2026-111497 numarasıyla takip edilen Node2Shell Brotli açığı, sıradan bir Node.js güvenlik güncellemesi olarak başladı ve iki gün içinde çok daha geniş bir soruna dönüştü. Node.js düzeltmeleri 21 Ekim'de yayınladı; 23 Ekim'de ise OpenAI aynı hatanın Google'ın Brotli kütüphanesinde olduğunu, dolayısıyla Bun, Envoy, Python binding'leri ve curl tabanlı istemcilere kadar uzandığını açıkladı. Node veya Python ile API geliştiriyorsanız, hele bir de Azure üzerinde çalışıyorsanız, tek bir runtime'ı güncellemek işin sadece başlangıcı. Loop olarak yaklaşımımız net: önce runtime'ı yamayın, sonra unuttuğunuz kopyaların peşine düşün.

Node2Shell Brotli açığında ne oldu?

21 Ekim 2026'da Node.js, desteklenen üç sürüm hattında (22.x, 24.x ve 26.x) güvenlik güncellemeleri yayınladı; her sürüm hattında kapatılan en yüksek önem derecesi High. En kritik olanı Brotli decompression tarafında.

Node.js'in duyurusuna göre streaming decoder, geçersiz bir block switch ile karşılaştığında bunu kalıcı bir format hatası olarak değil, geçici olarak "daha fazla input lazım" durumu olarak raporluyordu. Ardından gelen byte'ları sekiz byte'lık dahili bir buffer'a eklemeye devam ediyordu. Uygulamanın node:zlib ile açtığı Brotli verisini kontrol edebilen bir saldırgan, process belleğini bozabiliyor. Sonuç; çökme, process belleğinin sızması ya da uzaktan kod çalıştırma (RCE) olabiliyor. Node.js, açığı bildiren isimler olarak OpenAI Codex Security'den Khai Tran ve Sylvie Mayer'i gösteriyor.

Düzeltilmiş sürümler 22.23.4, 24.22.1 ve 26.12.1. Node.js 20 ise end-of-life durumda ve her end-of-life sürüm hattı gibi hiçbir düzeltme almıyor.

Güncellemeden sonra gelişmeler hızlandı:

  • 22 Ekim: Imperva, Linux arm64 için resmi Node.js 24.22.0 imajında, debugger ya da özel build kullanmadan kod çalıştırmayı başardı. Her denemede sonuç alamadı ama çalıştı. Yamalı 24.22.1'de aynı veri reddedildi. Imperva x86-64'ü, 22.x ve 26.x hatlarını ve arada kalan tüm Express ve body-parser sürümlerini test etmedi.
  • 23 Ekim: OpenAI, açığın Node.js, Bun ve Envoy gibi yazılımları etkilediğini ve iki yönlü çalıştığını söyledi: sıkıştırılmış veri kabul eden yamasız bir istemci, örneğin curl --compressed, kötü niyetli bir sunucu tarafından ele geçirilebilir. OpenAI ayrıca kök nedenin Brotli kaynak kodunda Şubat ayında zaten düzeltildiğini, ancak o dönem bunun bir güvenlik açığı olduğunun bilinmediğini belirtti.

CVE kaydı hatayı Brotli 1.0.3 ile 1.2.0 arasındaki sürümlere bağlıyor ve 1.0.10, 1.1.1 ya da 1.2.1'e geçilmesini öneriyor. CISA'nın 23 Ekim verilerine göre açık Known Exploited Vulnerabilities kataloğunda yer almıyor ve istismar durumu "none" olarak görünüyor. Bunu beklemek için değil, harekete geçmek için bir fırsat penceresi olarak görün.

Saldırgan decoder'a nasıl ulaşıyor?

Risk altında olmak için zlib'i doğrudan çağırmanız gerekmiyor. İki gayet sıradan kod yolu oraya çıkıyor.

Gelen request body'leri. Express 5 ve body-parser 2.x, Content-Encoding: br ile gelen request body'lerini otomatik açıyor ve bu header'ı herhangi bir istemci gönderebilir. Yalın bir Node.js HTTP sunucusu ise gelen Brotli body'lerini kendiliğinden açmıyor.

Dışarıya yapılan istekler. fetch() Brotli response'larını otomatik olarak açıyor. Saldırganın kontrol ettiği ya da ele geçirdiği bir sunucu, response üzerinden sizin process'inize ulaşabilir. Dışarıdan hiç trafik almayan servisler de buna dahil: bir partner API'ye ya da bir AI sağlayıcısına istek atan internal worker, dönen her şeyi decode ediyor.

Ekiplerin hafife aldığı yol genelde ikincisi. Webhook gönderimi, link önizleme, görsel proxy'leri ve tarama ya da "URL getir" aracı olan AI agent'lar, backend'inizin hangi sunucuyla konuşacağına kullanıcının karar vermesine izin veriyor.

Runtime'ı yamayın, sonra unutulan kopyaları bulun

Kendi bilgisayarınızda ve package.json içinde Node sürümünü yükseltmek sandığınızdan daha azını kapsıyor. Brotli; runtime'ların, işletim sistemi paketlerinin, dil binding'lerinin ve geliştirici araçlarının içine gömülü. İşi bitti saymadan önce envanter çıkarın:

Nerede Ne kontrol edilmeli Düzeltilmiş sürüm
Sunuculardaki ve CI runner'lardaki Node.js node -v 22.23.4 / 24.22.1 / 26.12.1
Container imajları Base image tag'i Aynı sürümler, pin'lenmiş
Python virtual environment'ları brotli, brotlicffi 1.2.1 / 1.2.1.0
Bun bun --version 1.4.4
İşletim sistemi paketleri brotli paketi Dağıtıma göre değişir
Single-executable uygulamalar Gömülü Node sürümü Yamalı Node ile yeniden build
Geliştirici makineleri Git for Windows, curl Üretici sürümlerini takip edin

Ekipleri en çok şaşırtan detaylar:

  • Container'lar: node:24.22.0'a pin'lenmiş bir Dockerfile, kaç kez yeniden build ederseniz edin açık kalır. Pin'i 24.22.1 veya üstüne taşıyın.
  • Python: advisory veritabanı kayıtları ancak 23 Ekim'de eklendi; yani dependency tarayıcılarınız geride kalmış olabilir. Kurulu sürümleri elle de kontrol edin.
  • Dağıtımlar kendi hızında ilerliyor: 23 Ekim itibarıyla Debian'ın güvenlik takipçisi, Debian 12 (bookworm) için düzeltilmiş brotli paketini (1.0.9-2+deb12u1) listeliyordu; Debian 13 (trixie) ve unstable ise hâlâ savunmasız görünüyordu.
  • Geliştirici araçları: 24 Ekim itibarıyla Git for Windows'un en güncel sürümü hâlâ Brotli 1.2.0 ile geliyordu.

Bir repo ve bir sunucu üzerinde hızlı bir ilk tarama:

node -p "process.version"
bun --version 2>/dev/null
python -m pip show brotli brotlicffi 2>/dev/null | grep -E "Name|Version"
grep -rn "FROM node:" --include="Dockerfile*" .

Maruziyet sırasına göre yamalayın

Her şeyi bugün güncelleyemiyorsanız, işi size kimin Brotli verisi gönderebildiğine göre sıralayın:

  1. Brotli açan body parser kullanan public route'lar. Express 5, body-parser 2.x. Anonim herhangi bir istemci bunlara ulaşabilir.
  2. Kullanıcının verdiği URL'yi çeken özellikler. Webhook'lar, link önizlemeleri, görsel proxy'leri, tarama aracı olan AI agent'lar.
  3. Üçüncü taraflara istek atan internal worker'lar. Hedef olma ihtimali daha düşük, ama ele geçirilmiş tek bir partner ya da sağlayıcı yeterli.
  4. CI runner'lar ve geliştirici makineleri. Özellikle dış sunuculara curl --compressed ile istek atan script'ler.

Node.js duyurusu bu açık için geçici bir workaround sunmuyor; Node'un içinde kapatabileceğiniz bir ayar yok. Çözüm, güncellemek.

Azure'da varsaymayın, çalışan process'i doğrulayın

Azure'da yama durumu işletim sistemine ve servise göre farklılık gösteriyor. Bu yüzden kontrolü çalışan uygulamanın içinden yapın.

  • Linux üzerinde App Service: Microsoft, güncellenmiş yerleşik Node.js ve Python imajlarının 22 Ekim itibarıyla hem Latest hem de Standard Platform Release Channel'larda dağıtımının tamamlandığını bildiriyor.
  • Windows üzerinde App Service: Microsoft'un yönlendirmesi, dağıtımın hızlandırılmış güvenli dağıtım süreciyle başladığını söylüyor; tamamlandığını söylemiyor. Platform Release Channel'lar Windows uygulamaları için geçerli değil ve Microsoft doğrulama için uygulamanın process.version değerine bakılmasını öneriyor.

Runtime sürümünü uygulama açılırken loglayın ki log stream'de ve Application Insights'ta görebilin:

console.log(`[startup] node=${process.version}`);

WAF'ı köprü olarak kullanın. Microsoft'a göre Application Gateway ve Azure Front Door üzerindeki Azure WAF, gelen saldırı vektörünü, yani uygulamanıza gönderilen Brotli ile sıkıştırılmış request body'lerini hafifletmeye yardımcı olabilir. Yama birkaç gün sürecekse açın. Ancak uygulamanızın başka sunuculardan çektiği response'lar için hiçbir şey yapmaz; Vercel de kendi firewall kurallarının bu response'ları kapsamadığını açıkça belirtiyor. WAF zaman kazandırır, güncellemenin yerini tutmaz.

Runtime yamalarını rutine dönüştürün

Bu olaydaki en çarpıcı detay OpenAI'ın paylaştığı bilgi: kod düzeltmesi aylardır Brotli'de duruyordu ama güvenlik etkisini kimse fark etmemişti; bağlantıyı yapay zekâ destekli zafiyet avcılığı kurdu. Benzer bulguların artmasını bekleyin ve tepkinizi sıradanlaştırın:

  • Minimum runtime sürümü tanımlayın. package.json içinde engines alanını ayarlayın ve altındaki kurulumları engelleyin:
{
  "engines": { "node": ">=24.22.1" }
}
  • Base imajları patch sürümüne pin'leyin ve güncellemeleri pull request üzerinden yapın; böylece her yükseltme görünür ve incelenebilir olur.
  • Advisory geldiğinde yeniden build edin. Bir runtime advisory'si yayınlandığında CI'ın imajları yeniden build edip deploy etmesini sağlayın, bir sonraki feature release'i beklemeyin.
  • Desteklenen sürüm hatlarında kalın. Node.js 20 bu sefer hiçbir şey almadı.
  • Runtime envanteri tutun. Hangi servisin hangi Node, Python ve Bun sürümüyle çalıştığını bilin ki bir sonraki advisory bir soruşturma değil, basit bir sorgu olsun.

Öne çıkanlar

  • Node2Shell (CVE-2026-111497), belleği bozup uzaktan kod çalıştırmaya yol açabilen bir Brotli decoder hatası; düzeltilmiş Node.js sürümleri 22.23.4, 24.22.1 ve 26.12.1, Node.js 20 ise düzeltme almıyor.
  • Kök neden Google'ın Brotli kütüphanesinde; Bun, Python'daki brotli ve brotlicffi, Envoy, curl ve içinde Brotli barındıran araçlar da kontrol edilmeli.
  • Risk, Express 5 tarzı body parsing'den ve internal servisler dahil fetch() response'larından geliyor.
  • Önce Brotli açan public route'ları, ardından kullanıcının verdiği URL'yi çeken özellikleri yamalayın.
  • Azure'da, özellikle Windows tarafında, process.version değerini çalışan uygulamanın içinden doğrulayın; WAF kurallarını yalnızca gelen trafik için geçici bir köprü olarak görün.
  • Patch sürümlerini pin'leyin, minimum engine tanımlayın ve advisory'lerde otomatik rebuild kurun ki bir sonraki açık rutin bir iş olsun.