Direkt zum Hauptinhalt springen
eLearner.app
Modul 8 · Lektion 4 von 432/32 im Kurs~14 min
Lektionen des Moduls (4/4)

ReDoS-sichere Muster schreiben

ReDoS (Regular expression Denial of Service) ist eine Klasse von Angriffen, bei denen eine sorgfältig konstruierte Eingabe die Matching-Zeit einer Regex explodieren lässt. Die JS-Engine verwendet Backtracking: Wenn ein Muster "ambivalent" ist, kann sie bei einer ungünstigen Eingabe eine exponentielle Anzahl von Versuchen durchführen.

Das klassische katastrophale Muster

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

Um einen Treffer zu finden, versucht die Engine jede mögliche Partitionierung von "a" zwischen den beiden +-Quantifizierern. Bei 20 "a"s sind das 2^20 = ~1 Million Versuche. Bei 30 "a"s eine Milliarde.

Weitere gefährliche Beispiele:

  • (a*)*b -- "verschachtelte Sterne".
  • (a|a)* -- überlappende Alternativen.
  • (\w+)+@ -- gierige Gruppen mit einem äußeren Quantifizierer.

Wie man die Gefahr erkennt

Suche nach diesen Strukturen:

  1. Quantifizierer innerhalb eines Quantifizierers: (...+)+, (...*)*, (...{n,})+.
  2. Überlappende Alternativen unter einem Quantifizierer: (a|ab)*, (\w|\d)+lock_content.
  3. Lookahead/Lookbehind mit komplexen Alternativen, die wiederholt werden.

Defensives Umschreiben

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

Die sichere Version trennt den Basisfall vom wiederholten Fall und beseitigt so die Mehrdeutigkeit. Weitere Techniken:

  • Possessive Quantifizierer (a++) -- in JS nicht unterstützt, aber in anderen Engines verfügbar.
  • Atomare Muster ((?>...)) -- nicht in JS.
  • Begrenzung der Länge der Eingabe vor dem Matching.
  • Timeout beim Matching (der Editor dieses Kurses verwendet einen Worker mit einem Timeout von 500 ms).

Empfehlungen für ReDoS-sichere Muster

  1. Stelle sicher, dass Optionen in einer Alternation sich gegenseitig ausschließen (z. B. verwende nicht (a|a+)).
  2. Vermeide es, verschachtelte Quantifizierer auf überlappende Ausdrücke anzuwenden (z. B. (\\s*)*).
  3. Bevorzuge immer spezifische negierte Zeichenklassen ([^\\n]*) gegenüber dem generischen Punkt-Wildcard (.*).

Probiere es aus

Übung#regex.m8.l4.e1
Versuche: 0Wird geladen…

Identifiziere Muster wiederholter Buchstaben -- aber auf eine ReDoS-sichere Weise. Verwende eine einzelne Zeichenklasse, KEINE verschachtelten Gruppen wie (a+)+.

Editor wird geladen…
Hinweis anzeigen

Ersetze das gefährliche (a+)+ durch ein einfaches a+. Das Ergebnis ist dasselbe, aber sicher.

Lösung nach 3 Versuchen verfügbar

Wiederholungsübung

Übung#regex.m8.l4.e2
Versuche: 0Wird geladen…

Erkenne eine Folge von Wörtern, die durch Leerzeichen getrennt sind, auf eine ReDoS-sichere Weise. Verwende die Struktur `(?:word+spaces+)*word` anstelle von `(word+space+)+`.

Editor wird geladen…
Hinweis anzeigen

Ersetze die Erfassungsgruppe (\w+\s+)+ durch die disjunkte Version (?:\w+\s+)*\w+.

Lösung nach 3 Versuchen verfügbar

Zusätzliche Herausforderung

Übung#regex.m8.l4.e3
Versuche: 0Wird geladen…

Mache das anfällige Muster `(\w+\s*)+:`, das ReDoS verursacht, sicher, indem du die überlappende Whitespace-Rekursion entfernst.

Editor wird geladen…
Hinweis anzeigen

Verschiebe das Leerzeichen, sodass es sich nicht mit der Gruppenwiederholung überlappt: (?:\w+\s+)*\w+:

Lösung nach 3 Versuchen verfügbar