Pelajaran modul (4/4)
Menulis pola aman ReDoS
ReDoS (Regular Expression Denial of Service) adalah kelas serangan yang mana masukan yang dibuat dengan cermat membuat waktu pencocokan regex meledak. Mesin JS menggunakan backtracking: jika suatu pola "ambigu", pada sebuah masukan yang tidak beruntung, ia dapat melakukan sejumlah percobaan secara eksponensial.
Pola bencana klasik
Pattern: ^(a+)+$
Input: "aaaaaaaaaaaaaaaaaaaaab"Agar cocok, mesin mencoba setiap kemungkinan partisi "a" di antaranya
dua bilangan +. Pada 20 "a", itu berarti 2^20 = ~1 juta percobaan.
Pada 30 "a", satu miliar.
Contoh berbahaya lainnya:
(a*)*b-- "bintang bersarang".(a|a)*-- alternatif yang tumpang tindih.(\w+)+@-- kelompok serakah dengan bilangan luar.
Bagaimana mengenali bahayanya
Carilah struktur ini:
- Penghitung di dalam pembilang:
(...+)+,(...*)*,(...{n,})+. - Alternatif yang tumpang tindih di bawah pembilang:
(a|ab)*,(\w|\d)+. - Melihat ke depan/melihat ke belakang dengan alternatif yang kompleks diulangi.
Penulisan ulang yang defensif
Dangerous: ^(\w+\s+)+$
Safe: ^(?:\w+\s+)*\w+$Versi aman memisahkan kasus dasar dari kasus berulang, dan menghapusnya ambiguitas. Teknik lainnya:
- Bilangan posesif (
a++) -- tidak didukung di JS, namun tersedia di mesin lain. - Pola atom (
(?>...)) -- tidak di JS. - Batasi panjang input sebelum mencocokkan.
- Batas waktu pada pencocokan (editor kursus ini menggunakan pekerja dengan batas waktu 500 ms).
Rekomendasi untuk pola aman ReDoS
- Pastikan opsi dalam pergantian saling eksklusif (misalnya, jangan gunakan
(a|a+)). - Hindari menerapkan bilangan bertingkat pada ekspresi yang tumpang tindih (misalnya
(\\s*)*). - Selalu lebih memilih kelas karakter tertentu yang dinegasikan (
[^\\n]*) daripada titik wildcard generik (.*).
Cobalah
Identifikasi pola huruf yang berulang -- tetapi dengan cara yang aman dari ReDoS. Gunakan kelas karakter tunggal, BUKAN grup bersarang seperti (a+)+.
Tunjukkan petunjuk
Gantikan (a+)+ yang berbahaya dengan a+ yang sederhana. Hasilnya sama, tapi aman.
Solusi tersedia setelah 3 upaya
Tinjau latihan
Kenali rangkaian kata yang dipisahkan spasi, dengan cara yang aman untuk ReDoS. Gunakan struktur `(?:kata+spasi+)*kata` alih-alih `(kata+spasi+)+`.
Tunjukkan petunjuk
Ganti grup penangkap (\\w+\\s+)+ dengan versi terpisah (?:\\w+\\s+)*\\w+.
Solusi tersedia setelah 3 upaya
Tantangan tambahan
Make the vulnerable pattern `(\w+\s*)+:` which causes ReDoS safe, by removing the overlapping whitespace recursion.
Tunjukkan petunjuk
Pindahkan spasi agar tidak tumpang tindih dengan pengulangan grup: (?:\\w+\\s+)*\\w+:
Solusi tersedia setelah 3 upaya