Vai al contenuto
eLearner.app
Modulo 8 · Lezione 4 di 432/32 nel corso~14 min
Lezioni del modulo (4/4)

Scrivere pattern ReDoS-safe

ReDoS (Regular expression Denial of Service) e' una classe di attacchi in cui un input ben costruito fa esplodere il tempo di matching di una regex. Il motore JS usa backtracking: se un pattern e' "ambiguo", su un input infelice puo' eseguire un numero esponenziale di tentativi.

Il pattern catastrofico classico

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

Per matchare, il motore prova tutte le partizioni possibili di "a" tra i due quantificatori +. Su 20 "a" sono 2^20 = ~1 milione di tentativi. Su 30 "a", un miliardo.

Altri esempi pericolosi:

  • (a*)*b -- "stelle nidificate".
  • (a|a)* -- alternative sovrapposte.
  • (\w+)+@ -- gruppi greedy con quantificatore esterno.

Come riconoscere il pericolo

Cerca queste strutture:

  1. Quantificatore dentro un quantificatore: (...+)+, (...*)*, (...{n,})+.
  2. Alternative sovrapposte sotto quantificatore: (a|ab)*, (\w|\d)+.
  3. Lookahead/lookbehind con alternative complesse ripetute.

Riscrittura difensiva

Code
Pericoloso:  ^(\w+\s+)+$
Sicuro:      ^(?:\w+\s+)*\w+$

La versione sicura separa il caso base dal caso ripetuto, eliminando l'ambiguita'. Altre tecniche:

  • Quantificatori possessivi (a++) -- non supportati in JS, ma in altri motori.
  • Pattern atomici ((?>...)) -- non in JS.
  • Limitare la lunghezza dell'input prima di matchare.
  • Timeout sul matching (l'editor di questo corso usa un worker con 500 ms di timeout).

Consigli per pattern ReDoS-safe

  1. Rendi disgiunte le scelte delle alternative (es. non usare (a|a+)).
  2. Evita di applicare quantificatori nidificati a espressioni sovrapponibili (es. (\\s*)*).
  3. Preferisci sempre classi di caratteri negative specifiche ([^\\n]*) rispetto al punto jolly generico (.*).

Prova tu

Esercizio#regex.m8.l4.e1
Tentativi: 0Caricamento…

Identifica pattern di lettere ripetute -- ma in modo ReDoS-safe. Usa una classe di caratteri singola, NON gruppi nidificati come (a+)+.

Caricamento editor…
Mostra suggerimento

Sostituisci il (a+)+ pericoloso con un semplice a+. Il risultato e' lo stesso, ma sicuro.

Soluzione disponibile dopo 3 tentativi

Esercizio di ripasso

Esercizio#regex.m8.l4.e2
Tentativi: 0Caricamento…

Riconosci una sequenza di parole separate da spazi, in modo ReDoS-safe. Usa la struttura `(?:parola+spazi+)*parola` invece di `(parola+spazio+)+`.

Caricamento editor…
Mostra suggerimento

Sostituisci il gruppo cattura (\\w+\\s+)+ con la versione disgiunta (?:\\w+\\s+)*\\w+.

Soluzione disponibile dopo 3 tentativi

Sfida aggiuntiva

Esercizio#regex.m8.l4.e3
Tentativi: 0Caricamento…

Rendi sicuro il pattern vulnerabile `(\w+\s*)+:` che causa ReDoS, eliminando la ricorsività sovrapposta degli spazi bianchi.

Caricamento editor…
Mostra suggerimento

Sposta gli spazi in modo che non si sovrappongano con la ripetizione del gruppo: (?:\w+\s+)*\w+:

Soluzione disponibile dopo 3 tentativi