Aikido

Warum man sich vor langsamen regulären Ausdrücken schützen sollte, um ReDoS-Angriffe zu verhindern

Lesbarkeit

Regel
Wache gegen langsam reguläre Ausdrücke.
Reguläre Ausdrücke mit verschachtelten Quantoren oder 
mehrdeutigen Mustern können verursachen. katastrophale 
Backtracking und Leistung Probleme.
Unterstützte Sprachen: 45+

Einleitung

Reguläre Ausdrücke können Ihre Anwendung mit der richtigen Eingabe für Sekunden oder Minuten einfrieren. Katastrophales Backtracking tritt auf, wenn Regex-Engines exponentiell zunehmende Pfade erkunden, während sie versuchen, ein Muster abzugleichen. Ein Regex wie (a+)+b dauert Mikrosekunden, um eine gültige Eingabe abzugleichen, kann aber Stunden dauern, um eine Zeichenkette von 'a's ohne nachfolgendes 'b' abzulehnen. Angreifer nutzen dies durch Regular Expression Denial of Service (ReDoS)-Angriffe aus, indem sie manipulierte Eingaben senden, die Ihre Regex-Engine dazu bringen, 100 % CPU zu verbrauchen, bis Anforderungs-Timeouts auftreten oder der Prozess abstürzt.

Warum es wichtig ist

Sicherheitsimplikationen (ReDoS-Angriffe): Ein Angreifer kann Ihre Anwendung mit einer einzigen Anfrage, die manipulierte Eingaben enthält, lahmlegen. E-Mail-Validierung und URL-Parsing-Muster sind häufige Ziele. Im Gegensatz zu herkömmlichen DoS-Angriffen, die Bandbreite erfordern, benötigt ReDoS nur winzige Payloads.

Leistungsverschlechterung: Normale Benutzereingaben können katastrophales Backtracking auslösen, wodurch die Antwortzeiten von Millisekunden auf Sekunden ansteigen. Dies führt zu unvorhersehbarer Latenz, die schwer zu debuggen ist, da sie nur bei spezifischen Eingabemustern auftritt.

Produktionsvorfälle: Anfällige Regex blockiert den Event-Loop in Node.js oder verbraucht Thread-Pool-Ressourcen. Wenn sich Anfragen häufen, steigt der Speicherverbrauch und das System reagiert nicht mehr. In Microservices führt eine anfällige Regex zu Kaskadenfehlern bei abhängigen Diensten.

Schwierigkeit bei der Erkennung: Muster, die bei Tests mit kurzen Eingaben einwandfrei funktionieren, werden bei längeren Eingaben exponentiell langsam. Die Schwachstelle bleibt oft bis zur Produktion unbemerkt und erfordert einen Notfall-Deployment während eines aktiven Incidents.

Code-Beispiele

❌ Nicht konform:

function validateEmail(email) {
    const regex = /^([a-zA-Z0-9_\-\.]+)+@([a-zA-Z0-9_\-\.]+)+\.([a-zA-Z]{2,5})$/;
    return regex.test(email);
}

function extractURLs(text) {
    const regex = /(https?:\/\/)?([\w\-])+\.(\w+)+([\w\-\.,@?^=%&:/~\+#]*)+/g;
    return text.match(regex);
}

Warum es unsicher ist: Die verschachtelten Quantoren ([a-zA-Z0-9_\\-\\.]+)+ exponentielles Backtracking erzeugen. Für eine E-Mail wie aaaaaaaaaaaaaaaaaaaaaaaaa!, versucht die Regex-Engine unzählige Kombinationen, bevor sie fehlschlägt. Die URL-Regex weist mehrere verschachtelte Quantifizierer auf, die das Problem verschärfen, wodurch sie mit Eingaben wie langen Zeichenketten gültiger Zeichen ohne die erwartete Struktur trivial ausnutzbar wird.

✅ Konform:

function validateEmail(email) {
    const regex = /^[a-zA-Z0-9_\-\.]+@[a-zA-Z0-9_\-\.]+\.[a-zA-Z]{2,5}$/;
    return regex.test(email);
}

function extractURLs(text) {
    const regex = /https?:\/\/[\w\-]+\.[\w\-]+(?:[\w\-\.,@?^=%&:/~\+#]*)?/g;
    return text.match(regex);
}

Warum es sicher ist: Das Entfernen verschachtelter Quantifizierer eliminiert katastrophales Backtracking. Einzelne Quantifizierer wie [a-zA-Z0-9_\-\.]+ werden in linearer Zeit ausgeführt. Das URL-Muster verwendet nicht-erfassende Gruppen mit optionalem Suffix (?:...)? anstelle von verschachtelten Wiederholungen, was eine vorhersehbare Leistung unabhängig von Eingabelänge oder Inhalt gewährleistet.

Fazit

Die Performance von regulären Ausdrücken ist ein Sicherheitsrisiko, nicht nur eine Optimierung. Überprüfen Sie alle Regex-Muster auf verschachtelte Quantifizierer, überlappende Zeichenklassen in Wiederholungsgruppen und mehrdeutige Alternativen. Testen Sie Regex-Muster mit pathologischen Eingaben (lange Zeichenketten gültiger Zeichen, gefolgt von ungültigen Endungen), um katastrophales Backtracking vor der Bereitstellung zu identifizieren. Ersetzen Sie, wenn möglich, komplexe Regex durch String-Parsing-Funktionen mit vorhersehbaren Performance-Eigenschaften.

FAQs

Haben Sie Fragen?

Welche Muster verursachen katastrophales Backtracking?

Häufige Übeltäter sind verschachtelte Quantifizierer wie (a+)+, (a*)* oder (a+)*b. Alternationen mit überlappenden Mustern wie (a|a)* oder (a|ab)*. Wiederholungen mit optionalen Komponenten wie (a?)+. Jedes Muster, bei dem die Regex-Engine denselben Teilstring auf mehrere Arten abgleichen kann, erzeugt einen exponentiellen Suchraum. Achten Sie auf Quantifizierer (+, *, {n,m}) innerhalb von Gruppen, die selbst quantifiziert sind.

Wie teste ich, ob mein Regex anfällig für ReDoS ist?

Verwenden Sie Online-Tools wie regex101.com, die Ausführungsschritte anzeigen und vor katastrophalem Backtracking warnen. Erstellen Sie Testeingaben mit langen Zeichenketten gültiger Zeichen, gefolgt von Zeichen, die Backtracking erzwingen. Für das Muster /^(a+)+b$/ testen Sie mit „aaaaaaaaaaaaaaa!“ (30+ a's, kein b). Wenn die Ausführung länger als Millisekunden dauert, ist der Regex anfällig. Implementieren Sie Timeouts in Regex-Operationen in der Produktion als Defense in Depth.

Was ist der Unterschied zwischen katastrophalem und linearem Backtracking?

Lineares Backtracking tritt auf, wenn der Regex-Engine Alternativen sequenziell ausprobiert, aber frühere Entscheidungen nicht neu bewertet. Der Aufwand wächst linear mit der Eingabegröße. Katastrophales Backtracking entsteht, wenn verschachtelte Quantifizierer die Engine zwingen, exponentiell viele Kombinationen auszuprobieren. Bei einer Eingabelänge von n kann die Ausführungszeit O(2^n) oder schlechter sein. Der Unterschied liegt zwischen Millisekunden und Minuten bei moderaten Eingabegrößen.

Kann ich Lookaheads und Lookbehinds sicher verwenden?

Lookaheads (?=...) and lookbehinds (?<=...) themselves don't cause catastrophic backtracking, but they can hide vulnerable patterns. A lookahead containing (a+)+ is still vulnerable. Use lookarounds for their intended purpose (assertions without consuming characters), not as a workaround for complex matching. Keep the patterns inside lookarounds simple and test them thoroughly.

Gibt es Regex-Engines, die katastrophales Backtracking verhindern?

RE2 (von Google verwendet) garantiert eine lineare Ausführungszeit, indem es Backtracking vollständig verbietet. Es unterstützt nicht alle Funktionen (Rückreferenzen, Lookarounds), verhindert aber ReDoS vollständig. Für kritische Sicherheitsprüfungen sollten RE2-Bindings oder ähnliche Engines in Betracht gezogen werden. Für JavaScript gibt es keine integrierte Alternative, daher sind Musterdesign und Timeouts Ihre primären Verteidigungsmechanismen.

Sollte ich Timeouts zu allen Regex-Operationen hinzufügen?

Für nicht vertrauenswürdige Eingaben (benutzergenerierte Daten, externe API-Antworten): Ja. Legen Sie angemessene Timeouts fest, z. B. 100-500 ms, abhängig von der erwarteten Komplexität. In Node.js können Sie regex.test() nicht direkt mit einem Timeout versehen, aber Sie können zuerst die Eingabelänge validieren oder regex in einem Worker-Thread mit Timeout ausführen. Lehnen Sie Eingaben ab, die angemessene Längenbeschränkungen überschreiten, bevor Sie versuchen, Regex-Abgleiche durchzuführen.

Wie behebe ich ein bestehendes anfälliges Regex-Pattern?

Bestimmen Sie zunächst, ob Sie überhaupt Regex benötigen. Viele Validierungsaufgaben sind mit String-Methoden wie includes(), startsWith() oder split() einfacher. Falls Regex notwendig ist, eliminieren Sie verschachtelte Quantifizierer, indem Sie das Muster abflachen. Ersetzen Sie (a+)+ durch a+. Verwenden Sie atomare Gruppen oder possessive Quantifizierer, falls Ihre Regex-Engine diese unterstützt. Für komplexe Muster sollten Sie in Betracht ziehen, die Eingabe in mehreren Durchläufen mit einfacheren Regex- oder String-Operationen zu parsen.

Werden Sie jetzt sicher.

Sichern Sie Ihren Code, Ihre Cloud und Ihre Laufzeit in einem zentralen System.
Finden und beheben Sie Schwachstellen schnell und automatisch.

Keine Kreditkarte erforderlich | Scan-Ergebnisse in 32 Sek.