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
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:
- Quantifizierer innerhalb eines Quantifizierers:
(...+)+,(...*)*,(...{n,})+. - Überlappende Alternativen unter einem Quantifizierer:
(a|ab)*,(\w|\d)+lock_content. - Lookahead/Lookbehind mit komplexen Alternativen, die wiederholt werden.
Defensives Umschreiben
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
- Stelle sicher, dass Optionen in einer Alternation sich gegenseitig ausschließen (z. B. verwende nicht
(a|a+)). - Vermeide es, verschachtelte Quantifizierer auf überlappende Ausdrücke anzuwenden (z. B.
(\\s*)*). - Bevorzuge immer spezifische negierte Zeichenklassen (
[^\\n]*) gegenüber dem generischen Punkt-Wildcard (.*).
Probiere es aus
Identifiziere Muster wiederholter Buchstaben -- aber auf eine ReDoS-sichere Weise. Verwende eine einzelne Zeichenklasse, KEINE verschachtelten Gruppen wie (a+)+.
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
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+)+`.
Hinweis anzeigen
Ersetze die Erfassungsgruppe (\w+\s+)+ durch die disjunkte Version (?:\w+\s+)*\w+.
Lösung nach 3 Versuchen verfügbar
Zusätzliche Herausforderung
Mache das anfällige Muster `(\w+\s*)+:`, das ReDoS verursacht, sicher, indem du die überlappende Whitespace-Rekursion entfernst.
Hinweis anzeigen
Verschiebe das Leerzeichen, sodass es sich nicht mit der Gruppenwiederholung überlappt: (?:\w+\s+)*\w+:
Lösung nach 3 Versuchen verfügbar