Bunu hemen çalıştırın. Kullandığınız sürüm aşağıdaki tablodaki eşik değerin altındaysa, Node.js Brotli RCE güvenlik açığından (CVE-2026-111497) etkileniyorsunuz demektir ve saldırganlar bu açığı şimdiden aktif olarak kullanıyor.
node -v
| Sürüm serisi | Güvenlik açığı bulunan | Düzeltilen sürüm | En güncel (5 Kas 2026) |
|---|---|---|---|
| 26.x | 26.12.1 altı | 26.12.1 | 26.13.0 |
| 24.x | 24.22.1 altı | 24.22.1 | 24.22.2 |
| 22.x | 22.23.4 altı | 22.23.4 | 22.23.4 |
| 25.x, 20.x ve daha eskileri | Kullanım Ömrü Bitti (End-of-Life): yamasız ve incelenmemiş | Düzeltme bulunmuyor | 24 veya 26 sürümüne geçin |
İkinci bir doğrulama yöntemi olarak, doğrudan ikili dosyaya (binary) sorabilirsiniz:
node -p "require('node:zlib').constants.BROTLI_DECODER_ERROR_FORMAT_BLOCK_SWITCH"
Bu sabit değer, yayınlanan düzeltmeyle birlikte eklendi. Desteklenen üç sürüm serisine ait dokuz resmi macOS derlemesinde bunu test ettik: düzeltilmiş her derleme -17 çıktısını verirken, daha eski derlemelerin tümü undefined döndürdü. Yine de öncelikle node -v çıktısına güvenin; çünkü yamayı geriye dönük uygulayan (backport eden) bir Linux dağıtımı bu sabiti eklememiş olabilir.
process.versions.brotli değerini kontrol etmeyle vakit kaybetmeyin. Bu değer hem 24.21.0 hem de 24.22.1 sürümlerinde 1.2.0; hem 22.23.3 hem de 22.23.4 sürümlerinde ise 1.1.0 çıktısını verdi. Node.js, raporlanan sürüm numarasını değiştirmeden düzeltmeyi cımbızlayıp (cherry-pick) uyguladığı için bu alan sisteminizin yamalı olup olmadığını gösteremez.
Özet (TL;DR)
| Soru | Yanıt |
|---|---|
| Nedir? | Node.js ile birlikte gelen Brotli kod çözücüsünde (decoder) bulunan, Node2Shell veya HTTP2Shell olarak da adlandırılan sınır dışı yazma (out-of-bounds write) açığı |
| Etki | Çökme, bellek sızıntısı veya uzaktan kod yürütme (RCE) |
| Kritiklik düzeyi | Node.js'e göre YÜKSEK (HIGH); NVD'ye göre 9.8 KRİTİK (CVSS 3.1) |
| Aktif olarak istismar ediliyor mu? | Evet. CISA KEV, 27 Ekim 2026'da kataloğuna ekledi |
| Kimlik doğrulama gerekiyor mu? | Hayır; NVD vektörüne ve Akamai'nin analizine göre gerekmiyor |
| Kimler risk altında? | Kendi kontrollerinde olmayan Brotli verilerini çözen uygulamalar: Express 5 gövdeleri (request bodies), fetch() yanıtları, doğrudan node:zlib çağrıları |
| Çözüm | Çalışma zamanını (runtime) güncelleyin, imajları yeniden derleyin, süreçleri (process) yeniden başlatın |
| Geçici bir çözüm var mı? | Güvenlik bildiriminde herhangi bir geçici çözüm belirtilmiyor. Aşağıdaki önlemler risk yüzeyini daraltır ancak tüm senaryoları kapsamaz |

ELLIO, düzeltmenin yayınlanmasından beş gün sonra, yani 26 Ekim itibarıyla sensörlerinde istismar trafiği tespit ettiğini bildirdi. Yakalanan saldırı yükü (payload), x86-64 mimarisindeki Node.js 24.22.0 sürümünü hedefliyordu. Bu saldırı yükünün son aşaması ELLIO’nun testlerinde başarısız olsa da, ELLIO standart 24.22.0 derlemelerinde kod yürütmenin bizzat mümkün olduğunu doğruladı. CISA, ABD federal kurumlarına önlem almaları için 10 Kasım’a kadar süre tanıdı ve fidye yazılımı (ransomware) kullanım durumunu "Bilinmiyor" olarak işaretledi. Akamai’nin telemetri verileri ise 26 Ekim itibarıyla ağların %61'inin etkilenen sürümleri çalıştırdığını gösterdi.
Node2Shell açıklaması: Brotli açığı ne yapıyor?
Node2Shell, Node.js çalışma zamanı ile birlikte gelen Brotli kod çözücüsünde bulunan bir sınır dışı yazma (out-of-bounds write) açığıdır. Hatalı biçimlendirilmiş sıkıştırılmış bir veri akışı, kod çözücünün sekiz baytlık dahili bir arabelleğin (buffer) sınırını aşarak yazmasına neden olur ve bu da süreç belleğini bozar. Bunun sonucunda uygulama çökebilir, bellek verileri sızabilir veya sunucunuzda saldırganın kontrolünde kod çalıştırılabilir.
Açığın temel nedeni, hatalı sınıflandırılan bir hata durumudur. Geçersiz bir blok değişimi, "bu veri bozuk" uyarısı vermek yerine "daha fazla girdiye ihtiyacım var" şeklinde değerlendirildi; bu nedenle akış kod çözücüsü, o küçük arabelleğe bayt eklemeye devam etti.
Hata, Google'ın Brotli kütüphanesinin 1.0.3 ile 1.2.0 arasındaki sürümlerinde yer alıyor; bu yüzden sorun yalnızca Node.js ile sınırlı değil. Node.js, ana projedeki (upstream) 0ed4268a numaralı commit'i cımbızlayarak (cherry-pick) 24.22.1 sürümüne ve eş zamanlı diğer sürümlerine aktardı ve kendi kopyasını düzeltti. Açık, OpenAI Codex Security araştırmacıları Khai Tran ve Sylvie Mayer tarafından bildirildi.
Bağımlılık tarayıcınız (dependency scanner) bu açığı yakalayamaz; çünkü kod çözücü bir paket olarak değil, doğrudan çalışma zamanının içinde gelir. Yamalanmamış Node.js 24.15.0 üzerinde çalıştırdığımız Express 5 test projesinde npm install komutu 0 güvenlik açığı bildirdi.
Kimler risk altında?
Güvenlik açığı bulunan bir çalışma zamanı, riskin yalnızca ilk yarısıdır. Diğer yarısı ise güvenilmeyen Brotli verilerini kod çözücüye ileten bir yolun (path) bulunmasıdır. Node.js 24.22.1 üzerinde her bir yolu, Content-Encoding: br başlığıyla zararsız ve geçersiz bir gövde (not-valid-brotli metni) göndererek ve her istemciye geçerli Brotli verisi sunarak test ettik.
| Kullanım Yolu | Test Edilen Sürüm | Kod çözücüyü çalıştırıyor mu? | Gözlemlediğimiz Sonuç |
|---|---|---|---|
Express 5 express.json() |
5.3.0 (body-parser 2.4.0) | Evet, varsayılan olarak | 400, “Decompression failed” |
Express 4 express.json() |
4.22.3 (body-parser 1.20.9) | Hayır | 415, desteklenmeyen kodlama (unsupported encoding) |
Koa @koa/bodyparser |
6.1.0 | Evet, varsayılan olarak | 500, günlükte BrotliDecoder hatası |
@fastify/compress ile Fastify |
9.3.0 | Evet, kaydedildikten sonra | 400, FST_CP_ERR_INVALID_CONTENT |
| Yalın Fastify | 5.12.8 | Hayır | 400, geçersiz JSON |
Yalın node:http sunucusu veya http.get |
24.22.1 | Hayır | Ham baytlar doğrudan iletildi |
Yerleşik fetch() |
24.22.1 | Evet, her zaman | Yanıtın kodunu çözdü |
| axios, got, node-fetch | 1.21.0, 16.2.0, 3.3.2 | Evet, varsayılan olarak | Yanıtın kodunu çözdü |
zlib.brotliDecompress*, createBrotliDecompress |
Tümü | Evet | Bu doğrudan kod çözücü API'sidir |

İki sonucun üzerinde özellikle durmak gerekiyor. fetch(), istek Accept-Encoding: identity başlığıyla gönderilse bile Brotli kodunu çözdü; çünkü talep ettiğiniz değere değil, gelen yanıt başlığına bakar. Uygulamanızın çağrı yaptığı herhangi bir sunucu kod çözücüye erişebilir; bu nedenle webhook test araçları, bağlantı önizleyicileri veya URL içe aktarıcıları doğrudan risk altındadır. Ayrıca tek başına bir 400 yanıtı hiçbir şeyi kanıtlamaz: Hem Express 5 hem de yalın Fastify 400 döndürür, ancak yalnızca Express 5 kod çözücüyü çalıştırır. Hata mesajını mutlaka okuyun.
Sisteminizdeki yolları üç komutla tespit edebilirsiniz:
# Direct decoder use
grep -rnE "brotliDecompress|createBrotliDecompress" src/
# Parsers that decode request bodies
npm ls express body-parser @koa/bodyparser @fastify/compress
# Base images and pinned versions
grep -rnE "^FROM .*node" --include='Dockerfile*' .
Tek bir yeni fetch() çağrısı bile tüm bu tabloyu değiştirebilir; bu nedenle sisteminiz "erişilebilir durumda olmasa" dahi mutlaka yama uygulamanız gerekir.
CVE-2026-111497 nasıl yamalanır?
Yalnızca tablodaki asgari eşik sürüme değil, serinizdeki en son derlemeye geçiş yapın. 5 Kasım itibarıyla bu kaynakların tümü düzeltilmiş derlemeleri içeriyordu:
| Kurulum yöntemi | Yapılması gereken |
|---|---|
| nvm | nvm install 24 && nvm alias default 24 |
| Homebrew | brew upgrade node (veya node@24, node@22) |
| Docker | FROM node:24.22.2-slim, ardından docker build --pull |
| Linux dağıtım paketleri | Dağıtımınızın güvenlik bildirimini takip edin; zira düzeltmeyi daha eski bir sürüm numarası altında geriye dönük uygulamış (backport etmiş) olabilirler |
| CI | .nvmrc, engines ve node-version alanlarını güncelleyin, ardından yeniden derleyin |
| Sunucusuz mimariler (Serverless) | Dağıtılmış bir fonksiyondan process.version çıktısını günlüğe yazdırın; platformun bunu otomatik güncellediğini varsaymayın |
Ardından çoğu kişinin gözden kaçırdığı şu iki açığı kapatın:
- Her şeyi yeniden başlatın. Çalışan bir süreç (process) eski ikili dosyayı bellekte tutmaya devam eder; bu nedenle disk üzerindeki sürümü güncellemek, pm2, systemd veya orkestrasyon aracınız süreci yeniden başlatana kadar hiçbir şeyi değiştirmez.
- Dağıttığınız her şeyi yeniden derleyin. Eski imajlar eski çalışma zamanını barındırmaya devam eder; ayrıca digest (özet) ile sabitlenmiş imajlar etiket üzerinden anlaşılamayacağı için imaj taramasından geçirilmelidir.
Son olarak, bu yazının başındaki kontrolleri önce dağıtılan kapsayıcı (container) içinde, ardından CI çalıştırıcılarında (runners) ve geliştirici makinelerinde yürütün. Her sürüm serisi için en yeni güvenlik derlemesini görmek için:
curl -s https://nodejs.org/dist/index.json | jq -r '[.[] | select(.security == true and (.version | test("^v(22|24|26)\\.")))] | group_by(.version | split(".")[0]) | .[] | max_by(.date) | "\(.version) \(.date)"'
Hâlâ 20 veya 25 sürümünde misiniz? Sizin için herhangi bir derleme bulunmuyor. Node.js 20 Kullanım Ömrü Sonu (End-of-Life) planını inceleyin ve sürümünüzü yükseltin.
Bugün yama uygulayamıyorsanız kullanabileceğiniz Node.js Brotli geçici önlemleri
Bu önlemler size zaman kazandırır; ancak hiçbiri sürüm yükseltmenin yerini tutmaz.
brkodlamasını uç noktada (edge) reddedin. Proxy veya yük dengeleyicinizde (load balancer) büyük/küçük harf duyarsız olarak vegzip, brgibi liste formatlarını da kapsayacak şekildeContent-Encoding: brbaşlığını engelleyin.- Uygulama içinde reddedin. Gövde ayrıştırıcılarınızdan (body parsers) önce bu kodu ekleyin. Express 5 testimizde 415 yanıtı döndürdü:
app.use((req, res, next) => {
const encoding = req.headers['content-encoding'] || '';
if (/\bbr\b/i.test(encoding)) return res.status(415).end();
next();
});
- Gövde açmayı (inflation) kapatın.
express.json({ inflate: false })aynı istek için 415 döndürdü. Bu ayar gzip gövdelerini de reddeder; bu yüzden önce istemcilerinizi kontrol edin. - Giden yanıtları kontrol altına alın. axios,
decompress: falseseçeneğini destekler; testimizde bu ayar baytları çözülmemiş olarak bıraktı.fetch()için standart bir kapatma mekanizması yoktur; bu nedenle bir izin verilenler listesi (allowlist) ve giden trafik (egress) kurallarıyla erişebileceği ana makineleri kısıtlayın. - Etki alanını (blast radius) sınırlandırın. Node.js servislerini ayrıştırın (segmentation) ve core dump dosyalarını okuyabilecek kişileri kısıtlayın; çünkü ELLIO çökmelerin bellek içi verileri buraya sızdırabileceğini belirtiyor.
ELLIO'nun ilk tespit ettiği işaretlere dikkat edin: Hangi sunucuların bunları çözdüğünü haritalandırmak için gönderilen ani Brotli kodlu istek gövdesi dalgalanmaları. Bir JSON API'sinde beklenmedik Content-Encoding: br trafiği veya worker çökmelerindeki ani artış, mutlaka incelenmesi gereken durumlardır.
API'nizin güncellemeden sorunsuz çıktığını doğrulayın: Testleri yapay zeka aracınıza yaptırın
Çalışma zamanı sürüm atlamaları TLS, DNS ve HTTP davranışlarını değiştirebilir; nitekim Ekim sürümü her üçüne de dokundu. Farkları manuel olarak karşılaştırmakla uğraşmayın. Kodlama aracınızın güncelleme öncesinde ve sonrasında Apidog CLI çalıştırmasını sağlayın ve nelerin değiştiğini raporlayın.
npm install -g apidog-cli@latest
apidog login --with-token <YOUR_TOKEN>
npx -y skills add https://apidog.com # pick your agent when prompted
Aracınıza tek bir prompt verin:
Run Apidog test suite <id> in project <id> against staging and save the
results to reports/before. After I upgrade Node.js, add a test case for
POST /orders that sends the plain text "not-valid-brotli" with
Content-Encoding: br, asserts a 4xx status, then checks GET /health
returns 200. Rerun the suite to reports/after and list every request
whose result changed.
Araç şu komutları çalıştırır:
apidog run --test-suite <id> --project <id> -e <envId> -r cli,junit --out-dir reports/before
apidog cli-schema get test-case-create
apidog cli-schema validate test-case-create --file case.json
apidog test-case create --project <id> --file case.json
apidog run --test-case <caseId> --project <id> -e <envId> -r cli,json
apidog run --test-suite <id> --project <id> -e <envId> -r cli,junit --out-dir reports/after
Bu ek test durumu bir istismar değil, sağlık kontrolüdür (health check): gövde düz metindir ve testimizde hem açık barındıran hem de düzeltilmiş derlemelerde aynı doldurma (padding) hatasıyla başarısız olmuştur. Yine de gerçek bir açığı yakalar: Koa testimiz, kod çözme hatası işlenmediği için 500 döndürdü; oysa herkese açık bir API'nin 4xx ile yanıt vermesi gerekir. Bunu yalnızca hazırlık (staging) ortamında çalıştırın.
run komutu başvuru kılavuzu tüm parametreleri listeler ve CI/CD kılavuzu aynı JUnit test çalıştırmasını dağıtım hattınıza (pipeline) entegre etmenizi sağlar. Apidog'un Ücretsiz planı 4 kullanıcıya kadar destek sunar.
11 Kasım tarihi neden kritik?
Node.js projesi, 11 Kasım 2026 tarihinde veya hemen sonrasında 26.x, 24.x ve 22.x için en yüksek önem derecesi yine YÜKSEK (HIGH) olan yeni bir sürümü önceden duyurdu. Henüz kamuya açıklanmış bir CVE bulunmuyor. Kasım sürümü rehberimiz bu güncellemeye nasıl hazırlanacağınızı ele alıyor.
Brotli yamasını o tarihe ertelemek yerine hemen şimdi uygulayın. Bu açığın detayları artık kamuya açık ve halihazırda aktif saldırı trafiği mevcut; üstelik bu hafta yapacağınız yükseltme bir sonrakinin provası niteliğindedir: aynı envanter, aynı imaj yeniden derlemeleri, aynı test paketi. PHP2Shell ve React2Shell de aynı süreçten geçmişti.
SSS
CVE-2026-111497 aktif olarak istismar ediliyor mu? Evet. CISA, 27 Ekim 2026'da Google Brotli başlığı altında bu açığı Bilinen İstismar Edilen Güvenlik Açıkları (KEV) kataloğuna ekledi ve ELLIO 26 Ekim itibarıyla istismar trafiği kaydetti.
Açık yüksek mi yoksa kritik düzeyde mi? Her iki tanım da geçerlidir. Node.js açığı YÜKSEK (HIGH) olarak değerlendiriyor. NVD, CVSS 3.1 kapsamında 9.8 KRİTİK (CRITICAL) puanı verirken Google'ın belirlediği CVSS 4.0 puanı 9.2'dir. Planlamanızı açığın aktif olarak istismar edildiği gerçeğini göz önüne alarak yapın.
Express 4 kullanıyorum. Güvende miyim? İstek gövdeleriniz (request bodies) kod çözücüye ulaşmaz; ancak fetch(), axios ve doğrudan node:zlib çağrıları yine de ulaşır. Ayrıca aynı sürümde dokuz farklı CVE daha düzeltildi; bu nedenle her halükarda güncelleme yapın.
Node.js 20 etkileniyor mu? Proje, Kullanım Ömrü Biten (End-of-Life) serileri değerlendirmeye almaz ve bu sürümler için herhangi bir düzeltme yayınlanmaz. 20.x ve 25.x sürümlerini yamasız ve güvenlik değerlendirmesi yapılmamış kabul edin ve sürüm yükseltin.
Bu durum Node.js dışındaki sistemleri de etkiliyor mu? Evet. GitHub güvenlik bildirimi PyPI'daki brotli ve brotlicffi paketlerini de kapsıyor; ayrıca üreticiler Bun 1.4.4 ve .NET için düzeltmeler bildirmiştir. Her kod çözücüyü ayrı ayrı güncelleyin; çünkü Node.js güncellemesi yalnızca kendi bünyesindeki kopyayı düzeltir.
