Ana içeriğe geç
Modül 8 · Ders 4 ders 4Kurstaki 32/32~14 min
Modül dersleri (4/4)

ReDoS güvenli kalıpların yazılması

ReDoS (Normal ifade Hizmet Reddi), bir saldırı sınıfıdır. Dikkatlice hazırlanmış bir girdi, bir regex'in eşleşme zamanının patlamasına neden olur. JS motoru geri izleme kullanır: eğer bir kalıp "belirsiz" ise, şanssız giriş, üstel sayıda deneme gerçekleştirebilir.

Klasik felaket modeli

Code
Pattern: ^(a+)+$
Input:   "aaaaaaaaaaaaaaaaaaaaab"

Eşleştirmek için motor, "a"nın her olası bölümünü dener. iki + niceleyici. 20 "a"da bu 2^20 = ~1 milyon denemedir. 30 "a" ile bir milyar.

Diğer tehlikeli örnekler:

  • (a*)*b -- "yuvalanmış yıldızlar".
  • (a|a)* -- örtüşen alternatifler.
  • (\w+)+@ -- dış niceleyiciye sahip açgözlü gruplar.

Tehlike nasıl fark edilir

Bu yapıları arayın:

  1. Bir niceleyici içindeki niceleyici: (...+)+, (...*)*, (...{n,})+.
  2. Bir niceleyici altında örtüşen alternatifler: (a|ab)*, (\w|\d)+.
  3. Karmaşık alternatiflerle ileri/geriye bakış tekrarlandı.

Savunma amaçlı yeniden yazma

Code
Dangerous:  ^(\w+\s+)+$
Safe:       ^(?:\w+\s+)*\w+$

Güvenli sürüm, temel durumu tekrarlanan durumdan ayırarak belirsizlik. Diğer teknikler:

  • İyelik niceleyiciler (a++) -- JS'de desteklenmez ancak diğer motorlarda mevcuttur.
  • Atomik kalıplar ((?>...)) -- JS'de değil.
  • Eşleştirmeden önce girişin uzunluğunu sınırlayın.
  • Eşleştirmede zaman aşımı (bu kursun düzenleyicisi 500 ms zaman aşımı olan bir çalışan kullanır).

ReDoS güvenli modeller için öneriler

  1. Alternatif olarak seçeneklerin birbirini dışladığından emin olun (örn. (a|a+) kullanmayın).
  2. Çakışan ifadelere iç içe niceleyiciler uygulamaktan kaçının (ör. (\\s*)*).
  3. Her zaman genel joker karakter noktası (.*) yerine belirli olumsuzlanmış karakter sınıflarını ([^\\n]*) tercih edin.

Deneyin

Egzersiz#regex.m8.l4.e1
Denemeler: 0Yükleniyor…

Tekrarlanan harf kalıplarını ReDoS açısından güvenli bir şekilde tanımlayın. (a+)+ gibi iç içe geçmiş gruplar DEĞİL, tek bir karakter sınıfı kullanın.

Düzenleyici yükleniyor…
İpucu göster

Tehlikeli (a+)+'yı basit bir a+ ile değiştirin. Sonuç aynı ama güvenli.

3 denemeden sonra çözüm mevcut

Alıştırmayı gözden geçirin

Egzersiz#regex.m8.l4.e2
Denemeler: 0Yükleniyor…

Boşluklarla ayrılmış bir kelime dizisini ReDoS açısından güvenli bir şekilde tanıyın. `(kelime+boşluk+)+` yerine `(?:kelime+boşluk+)*kelime` yapısını kullanın.

Düzenleyici yükleniyor…
İpucu göster

Yakalama grubunu (\\w+\\s+)+ ayrık sürümle (?:\\w+\\s+)*\\w+ ile değiştirin.

3 denemeden sonra çözüm mevcut

Ek zorluk

Egzersiz#regex.m8.l4.e3
Denemeler: 0Yükleniyor…

Make the vulnerable pattern `(\w+\s*)+:` which causes ReDoS safe, by removing the overlapping whitespace recursion.

Düzenleyici yükleniyor…
İpucu göster

Alanı grup tekrarıyla çakışmayacak şekilde taşıyın: (?:\\w+\\s+)*\\w+:

3 denemeden sonra çözüm mevcut