Regex-Leistung und Validierung: mehrdeutige Muster vermeiden
Reguläre Ausdrücke eignen sich für lokale Formprüfungen: Präfixe, Trennzeichen oder Längen. Sie beweisen nicht, dass Daten richtig, sicher oder günstig zu verarbeiten sind. Ein Muster kann einen falschen Wert akzeptieren, ein anderes kann bei einer fast passenden Eingabe zu lange laufen. Diese Anleitung verwendet synthetische Beispiele, um Leistung und Validierung zu prüfen, ohne ein langsames Muster zu einer Angriffsanleitung zu machen.
Das Problem
Das Risiko entsteht, wenn mehrere Teile eines Ausdrucks denselben Text verbrauchen können und die Engine vor dem Fehlschlag viele Aufteilungen versucht. Verschachtelte Quantifizierer, überlappende Alternativen und mehrdeutige Enden sind typische Warnzeichen. Bei Backtracking-Engines kann eine lange, fast gültige Eingabe immer wieder zu früheren Entscheidungen zurückführen. Das kann eine Oberfläche blockieren, CPU verbrauchen oder einen Dienst unbrauchbar machen. OWASP bezeichnet diese Klasse als ReDoS, wenn eine andere Person die Eingabe steuern kann.
Nicht jeder Ausdruck mit Klammern oder Sternen ist gefährlich. Kosten hängen von Engine, gesamtem Muster, Eingabegrenzen und Aufruf ab. Trotzdem ist es schlechte Gestaltung, auf einen Vorfall zu warten. Ein Feld sollte Format, Höchstlänge und Verhalten bei Nichtübereinstimmung beschreiben. Repräsentiert die Regel Identität, Geschäftsentscheidung oder Betrag, braucht sie zusätzlich semantische Prüfungen außerhalb des Ausdrucks.
/regex-tester hilft beim Untersuchen nicht sensibler Testwerte. Er beweist weder Sicherheit für jede Länge noch ersetzt er die Grenzen des empfangenden Systems. Halte Engine, Flags und Grenzen fest, denn Syntax und Verhalten unterscheiden sich zwischen Sprachen. Die ECMAScript-Spezifikation beschreibt JavaScript-RegExp; ein Backend kann eine andere Bibliothek einsetzen.
Praktisches Beispiel
Betrachte den Demonstrationsausdruck ^(a+)+$. Das wiederholte äußere Element enthält selbst einen Quantifizierer und kann eine Folge von a auf viele Arten aufteilen. Untersuche ihn nur mit einem kurzen passenden Wert wie aaaa und einem fast passenden Wert mit anderem Endzeichen wie aaaa!. Erhöhe die Länge nicht aggressiv und führe das Beispiel nicht gegen echte Anfragen aus. Ziel ist, Mehrdeutigkeit zu erkennen, nicht möglichen Schaden zu messen.
Für die erfundene Anforderung „ein bis sechzig Kleinbuchstaben a“ lautet eine begrenzte Alternative ^a{1,60}$. Sie macht das Maximum sichtbar und lässt eine relevante Prüfung pro Zeichen zu. aaaa ist gültig; aaaa!, eine leere Zeichenkette und 61 Buchstaben sind ungültig. Sechzig ist keine allgemeine Empfehlung, sondern gehört nur zu diesem fiktiven Feld. Eine echte Kennung benötigt Alphabet, Normalisierung und Länge aus ihrem Vertrag.
Der Vergleich zeigt zwei Punkte. Kurze Syntax ist nicht automatisch klare Bedeutung; die begrenzte Variante zeigt den Höchstwert für die Prüfung. Auch ein boolesches Ergebnis erklärt nicht, warum ein Wert zulässig ist. Ein Muster kann acht alphanumerische Zeichen verlangen, aber nicht beweisen, dass ein Konto existiert, zwei Daten ein gültiges Intervall bilden oder ein Betrag erlaubt ist. Dafür sind Daten und zusätzliche Regeln nötig.
Vorgehensweise
Beschreibe den Wert zuerst in normaler Sprache. Lege fest, ob leer, Unicode, führende oder nachfolgende Leerzeichen, Trennzeichen und jede Länge zulässig sind. Entscheide, wo Normalisierung stattfindet; Abschneiden, Großschreibung oder Unicode-Normalisierung nach der Prüfung kann Bedeutung ändern. Wenn die Regel ohne Anzeige des Musters nicht erklärbar ist, sind Format und Geschäftslogik wahrscheinlich vermischt.
Erstelle danach eine kleine Tabelle repräsentativer Werte: normal gültig, Minimum, Maximum, ähnliche aber verbotene Zeichen, leer und zu lang. Nutze synthetische Daten. Führe sie in der tatsächlichen Engine der Anwendung aus und notiere Treffer, ungefähre Dauer und benötigte Gruppen. Regressionstests sollen Ergebnisse prüfen, nicht eine exakte Millisekundenzahl, die je nach Gerät schwankt.
Prüfe die Struktur vor einer Optimierung. Suche Wiederholungen in Wiederholungen, Alternativen, bei denen eine Option Präfix einer anderen ist, und unbegrenzte Platzhalter vor unsicheren Trennzeichen. Frage, ob ein Quantifizierer zu einem endlichen Intervall werden kann, ein Trennzeichen explizit sein kann oder Analyse in Schritte teilbar ist. Kopiere keine breiten Internetmuster für enge Felder; sie akzeptieren oft mehr als das Produkt benötigt.
Baue Schutz um den Ausdruck. Weise zu lange Eingaben vor der Auswertung ab, begrenze Request-Bodies und setze ein Zeitbudget, falls die Plattform es unterstützt. Im Browser sollte keine teure Regel ohne Maximum bei jedem Tastendruck laufen; begrenze Länge und verschiebe Arbeit bei Bedarf. Der Dienst braucht dieselben Grenzen, auch wenn der Client geprüft hat, weil eine Anfrage die Oberfläche umgehen kann.
Technische Erklärung
Eine Backtracking-Engine wählt einen Pfad und kehrt bei einem nicht passenden Ende zu einer früheren Wahl zurück. Bei ^(a+)+$ kann jede innere Gruppe unterschiedlich viele a nehmen; bei ! werden Kombinationen untersucht, die alle scheitern. Die beigefügte Grafik verspricht keine universellen Zeiten. Sie zeigt, warum ein mehrdeutiger Pfad deutlich schneller wächst als eine feste Begrenzung. Manche Engines optimieren Einzelfälle, doch Sicherheitsregeln dürfen nicht auf einer nicht garantierten Optimierung beruhen.
Die Anker ^ und $ zeigen die Absicht, den ganzen Text zu prüfen; Mehrzeilenoptionen und API bleiben jedoch wichtig. Eine Teilzeichenkette zu finden ist nicht dasselbe wie vollständige Übereinstimmung. Relevant ist auch, ob ein Regex-Objekt Zustand trägt und ob Eingaben vor dem Vergleich verändert werden. Lies Sprachdokumentation und teste den Integrationscode, nicht nur ein in eine Webseite eingefügtes Muster.
Regex eignet sich für kleine reguläre Grammatiken: erlaubte Präfixe, Trennzeichen, Zeichen und Grenzen. Semantische Validierung folgt danach: Zahl umwandeln und Bereich prüfen; Datum interpretieren und Kalender prüfen; erlaubte Werte nachschlagen; Berechtigungen auf dem Server vergleichen. Getrennte Phasen liefern verständliche Fehler und vermeiden einen riesigen Ausdruck, den niemand sicher prüfen kann.
Häufige Fehler
Ein häufiger Fehler ist, ein kopiertes Muster für E-Mail, URL oder Passwort als vollständige Spezifikation zu behandeln. Viele Formate haben Ausnahmen, Internationalisierung oder veränderliche Regeln. Ein zu strenger Ausdruck schließt berechtigte Menschen aus; ein zu weiter verlagert schwierige Arbeit. Definiere Produktpolitik und Grenzen, statt zu behaupten, ein Ausdruck implementiere einen ganzen externen Standard.
Ebenso problematisch sind Tests nur mit glücklichen Eingaben. Eine Regel kann zehn normale Beispiele treffen und bei einem langen, am letzten Zeichen scheiternden Wert schlechter werden. Ergänze Grenzfälle und teste lokal im echten Kontext. Veröffentliche oder automatisiere keine wachsenden Lasten gegen fremde Systeme. Erkenne Mehrdeutigkeit in einer lokalen Kopie und ersetze sie durch eine begrenzte Regel.
Browservalidierung ist keine Sicherheitsgrenze. Sie hilft beim Korrigieren, doch eine Anfrage lässt sich ohne Oberfläche bauen. Der Server muss Format, Länge, Berechtigungen und Geschäftsregeln erneut prüfen. Ausgabekodierung bleibt nötig: Ein Regex-Treffer macht Daten nicht sicher für HTML, SQL, Pfade oder Systembefehle.
Wichtige Überlegungen
Bevorzuge Grenzen aus der Domäne: 64 Zeichen weil das Feld es festlegt, vier Segmente weil das Protokoll es verlangt oder eine gepflegte endliche Liste. Miss Eingaben vor Umwandlung oder Speicherung. Sind Daten absichtlich groß, nutze einen passenden Parser oder verarbeite in Teilen; beschreibe kein ganzes Dokument mit einer einzeiligen Regex.
Dokumentiere Engine und Flags direkt bei der Regel. In JavaScript verändern Unicode-Modus, Groß-/Kleinschreibung und Zeichenklassen das Ergebnis. Prüfe Abhängigkeitsversionen, wenn ein Muster in eine Drittanbieter-Komponente gelangt. Bei sicherheitsrelevanten Regeln muss eine zweite Person Absicht, Beispiele und Grenzen lesen können, ohne jedes Metazeichen auswendig zu kennen.
Beobachte Fehler und Latenz, ohne vollständige sensible Werte zu speichern. Zähler für Längen- oder Formatfehler können zeigen, dass eine Regel bessere Erklärung braucht. Scheint Zeit auffällig, bewahre künstliche Formbeispiele auf und minimiere den Fall vor der Korrektur. Beobachtung hilft bei Prioritäten, ersetzt aber keine vorbeugende Grenze.
Grenzen
Diese Anleitung zertifiziert nicht, dass ein konkreter Ausdruck frei von ReDoS ist, und liefert kein Timeout für alle Browser, Server und Engines. Leistung hängt von Implementierung, Hardware, Parallelität und Eingabe ab. Das verschachtelte Beispiel dient nur kontrollierter Prüfung; es darf nicht als Validator ausgerollt oder zum Test fremder Dienste genutzt werden.
Auch ein begrenzter Ausdruck löst weder Authentifizierung noch Autorisierung, Identitätsnormalisierung, Injektionsschutz oder Datenschutz. Jeder Ausgabekontext braucht passende Kodierung und jede sensible Entscheidung vertrauenswürdige Kontrollen. Lies Engine-Dokumentation und einschlägige Sicherheitsleitfäden, bevor ein Muster an einer exponierten Grenze eingesetzt wird.
Checkliste
Beschreibe Daten und Grenzen vor dem Schreiben der Regex. Teste gültige, ungültige, leere und zu lange Werte in der echten Engine. Vermeide verschachtelte Quantifizierer und konkurrierende Alternativen; bevorzuge explizite Zeichenklassen und endliche Intervalle. Begrenze Größe vor der Auswertung und validiere erneut auf dem Server. Trenne Format und Semantik, halte Absicht und Flags fest, beobachte Fehler ohne Geheimnisse zu speichern und überprüfe jedes Muster auf einer öffentlichen Route.