Passer au contenu principal
eLearner.app
Module 8 · Leçon 4 sur 432/32 dans le cours~14 min
Leçons du module (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

Exercice#regex.m8.l4.e1
Tentatives : 0Chargement…

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

Chargement de l'éditeur…
Afficher l'indice

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

Solution disponible après 3 tentatives

Esercizio di ripasso

Exercice#regex.m8.l4.e2
Tentatives : 0Chargement…

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

Chargement de l'éditeur…
Afficher l'indice

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

Solution disponible après 3 tentatives

Sfida aggiuntiva

Exercice#regex.m8.l4.e3
Tentatives : 0Chargement…

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

Chargement de l'éditeur…
Afficher l'indice

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

Solution disponible après 3 tentatives