Kural:
Yavaş düzenli ifadelere karşı koruma
sağlayın. İç içe niceleyicilere veya
belirsiz kalıplara sahip düzenli ifadeler
felaket düzeyinde geri izlemeye (backtracking)
ve performans sorunlarına yol açabilir.
Desteklenen diller: 45+Giriş
Düzenli ifadeler (regex), doğru girdiyle uygulamanızı saniyelerce veya dakikalarca dondurabilir. Felaket düzeyindeki geri izleme (backtracking), regex motorları bir kalıbı eşleştirmeye çalışırken üstel olarak artan yolları keşfettiğinde meydana gelir. Şunun gibi bir regex: (a+)+b geçerli bir girdiyi mikrosaniyeler içinde eşleştirebilir, ancak takip eden bir b harfi olmaksızın bir dizi a harfini reddetmek saatler sürebilir. Saldırganlar bunu Düzenli İfade Hizmet Dışı Bırakma (ReDoS) saldırıları yoluyla istismar eder; regex motorunuzun istek zaman aşımı gerçekleşene veya işlem çökene kadar %100 CPU tüketmesine neden olan özel hazırlanmış girdiler gönderirler.
Neden önemli?
Güvenlik etkileri (ReDoS saldırıları): Bir saldırgan, özel olarak hazırlanmış girdi içeren tek bir istekle uygulamanızı felç edebilir. E-posta doğrulama ve URL ayrıştırma kalıpları yaygın hedeflerdir. Bant genişliği gerektiren geleneksel DoS saldırılarının aksine ReDoS yalnızca çok küçük yükler (payload) gerektirir.
Performans düşüşü: Normal kullanıcı girdisi felaket düzeyinde geri izlemeyi tetikleyebilir ve yanıt sürelerinin milisaniyelerden saniyelere fırlamasına neden olabilir. Bu durum, yalnızca belirli girdi kalıplarında ortaya çıktığı için hata ayıklaması zor olan öngörülemeyen bir gecikme yaratır.
Prodüksiyon olayları: Zafiyet içeren regex, Node.js'teki olay döngüsünü (event loop) bloke eder veya iş parçacığı havuzu (thread pool) kaynaklarını tüketir. İstekler biriktikçe bellek artar ve sistem yanıt vermez hale gelir. Mikro hizmetlerde, zafiyet içeren tek bir regex hataları bağımlı servislere zincirleme olarak aktarır.
Tespitteki zorluklar: Kısa girdilerle yapılan testlerde sorunsuz çalışan kalıplar, daha uzun girdilerle üstel olarak yavaşlar. Zafiyet genellikle prodüksiyona geçene kadar fark edilmez ve aktif bir olay sırasında acil bir dağıtım (deployment) yapılmasını gerektirir.
Kod örnekleri
❌ Kural dışı:
function validateEmail(email) {
const regex = /^([a-zA-Z0-9_\-\.]+)+@([a-zA-Z0-9_\-\.]+)+\.([a-zA-Z]{2,5})$/;
return regex.test(email);
}
function extractURLs(text) {
const regex = /(https?:\/\/)?([\w\-])+\.(\w+)+([\w\-\.,@?^=%&:/~\+#]*)+/g;
return text.match(regex);
}
Güvensiz olma nedeni: İç içe geçmiş niceleyiciler ([a-zA-Z0-9_\\-\\.]+)+ üstel geri izlemeye (backtracking) yol açar. Buna benzer bir e-posta adresinde aaaaaaaaaaaaaaaaaaaaaaaaa!, regex motoru başarısız olmadan önce sayısız kombinasyon dener. URL regex'i, problemi katlayan birden fazla iç içe geçmiş niceleyici içerir; bu da beklenen yapıya sahip olmayan uzun geçerli karakter dizileri gibi girdilerle burayı istismar etmeyi son derece kolaylaştırır.
✅ Kurallara uygun:
function validateEmail(email) {
const regex = /^[a-zA-Z0-9_\-\.]+@[a-zA-Z0-9_\-\.]+\.[a-zA-Z]{2,5}$/;
return regex.test(email);
}
function extractURLs(text) {
const regex = /https?:\/\/[\w\-]+\.[\w\-]+(?:[\w\-\.,@?^=%&:/~\+#]*)?/g;
return text.match(regex);
}
Güvenli olma nedeni: İç içe geçmiş niceleyicilerin kaldırılması felaket niteliğindeki geri izlemeyi (catastrophic backtracking) ortadan kaldırır. [a-zA-Z0-9_\-\.]+ gibi tekli niceleyiciler doğrusal zamanda yürütülür. URL deseni, iç içe tekrarlar yerine isteğe bağlı soneke (?:...)? sahip yakalamayan gruplar (non-capturing groups) kullanarak girdi uzunluğundan veya içeriğinden bağımsız olarak öngörülebilir bir performans sağlar.
Sonuç
Düzenli ifade (regex) performansı yalnızca bir optimizasyon meselesi değil, bir güvenlik konusudur. Tüm regex kalıplarını iç içe geçmiş niceleyiciler, tekrar gruplarındaki çakışan karakter sınıfları ve belirsiz alternatifler açısından gözden geçirin. Dağıtımdan önce felaket niteliğindeki geri izlemeleri tespit etmek için regex kalıplarını patolojik girdilerle (geçersiz bitişlerle takip edilen uzun geçerli karakter dizileri) test edin. Mümkün olduğunda, karmaşık regex'leri öngörülebilir performans özelliklerine sahip dize ayrıştırma (string parsing) fonksiyonlarıyla değiştirin.

