Skip to content

WAF-Regeln

WAF-Regeln sind der programmierbare Teil der Sicherheitsschicht von smoxy. Während die verwaltete WAF und die verwalteten Szenarien die Entscheidung abnehmen, beschreibt eine WAF-Regel die eigene Vorgabe: welcher Teil einer Anfrage geprüft wird, wie verglichen wird und was am Edge passieren soll, wenn die Regel greift — blockieren, per Challenge prüfen, drosseln, überspringen oder nur den Anomalie-Score der Anfrage erhöhen.

Regeln werden bei jeder Anfrage am Edge ausgewertet, im selben Durchlauf wie die Plattformregeln von smoxy. Eine gespeicherte Änderung ist innerhalb von Momenten aktiv.

Die Karte WAF-Regeln auf der WAF-Seite der Zone: eigene Regeln, die von Smoxy verwalteten Regeln und die Anzeige der Regelnutzung.Die Karte WAF-Regeln auf der WAF-Seite der Zone: eigene Regeln, die von Smoxy verwalteten Regeln und die Anzeige der Regelnutzung.
Die Karte WAF-Regeln auf der WAF-Seite der Zone: eigene Regeln, die von Smoxy verwalteten Regeln und die Anzeige der Regelnutzung.

INFO

Beta: Die Regel-Engine befindet sich in der Beta-Phase. Von der Plattform verwaltete Regeln gelten für jede Zone, und Details des Regelverhaltens können sich noch ändern.

Wo WAF-Regeln greifen

Die Regel-Engine ist die letzte Stufe der Sicherheitsschicht. Alles, was eine Anfrage ausnehmen kann, ist bereits gelaufen, wenn eine Regel ausgewertet wird:

Anfrage
Sicherheit
  1. 1
    IP-Listen
    Allowlist und Blocklist der Zone und global
  2. 2
    Access Rules
    Allow · Block · Challenge · Skip
  3. 3
    Reputation & Under Attack Mode
    Verdikte der verwalteten Szenarien
  4. 4
    WAF-Regeln
    eigene und von Smoxy verwaltete Regeln in einer sortierten Liste
Rewrite Rules ▸ Cache ▸ Origin

Aus dieser Reihenfolge folgen zwei Dinge für die Praxis:

  • Eine IP auf der Allowlist, ein verifizierter Suchmaschinen-Crawler oder eine Access Rule mit Allow oder Skip (waf) nimmt die Anfrage aus, bevor die Engine läuft. Keine WAF-Regel bekommt sie zu sehen. Für Monitoring-Werkzeuge und vertrauenswürdige Integrationen ist das der vorgesehene Weg.
  • Basic Auth läuft danach und wird von keiner WAF-Regel übersprungen. Eine skip-Regel verteilt keine Passwörter.

Den vollständigen Ablauf zeigt der Lebenszyklus einer Anfrage.

Zwei Arten von Regeln

Die Karte WAF-Regeln auf der WAF-Seite der Zone enthält zwei Listen:

ListeWem sie gehörtWas möglich ist
Eigene Regelnder Zoneanlegen, bearbeiten, löschen, aktivieren/deaktivieren
Von Smoxy verwaltete Regelnsmoxyeinzeln für diese Zone ein- oder ausschalten — die Regel selbst ist schreibgeschützt

Beide Listen werden am Edge zu einer einzigen Auswertungsliste zusammengeführt und nach Reihenfolge sortiert. Eine eigene Regel mit Reihenfolge 0 wird also vor einer verwalteten Regel mit Reihenfolge 10 ausgewertet. Verwaltete Regeln behandelt der Abschnitt Von Smoxy verwaltete Regeln.

Regelkontingent

Eine Zone hat standardmäßig 3 eigene WAF-Regeln. Die Karte zeigt eine WAF-Regelnutzung an (2 / 3, „1 Regel übrig“, „Limit erreicht“). Braucht eine Zone mehr, hilft der Support weiter.

Das Kontingent gilt nur für eigene Regeln. Verwaltete Regeln sind unbegrenzt und zählen nicht mit; vom gemeinsamen Kontingent der Access, Rewrite und Conditional Rules ist es ebenfalls getrennt.


Eine Regel anlegen

  1. Die Seite WAF der Zone öffnen (Sicherheit → WAF).
  2. In der Karte WAF-Regeln auf Regel hinzufügen klicken.
  3. Beschreibung, Bedingungen und Aktion ausfüllen.
  4. Mit Regel hinzufügen speichern.
Der Regeleditor: Beschreibung, Phase, Übereinstimmung und Reihenfolge, darunter die Bedingungen und die Aktion.Der Regeleditor: Beschreibung, Phase, Übereinstimmung und Reihenfolge, darunter die Bedingungen und die Aktion.
Der Regeleditor: Beschreibung, Phase, Übereinstimmung und Reihenfolge, darunter die Bedingungen und die Aktion.

Felder einer Regel

FeldBedeutung
BeschreibungEin Etikett mit bis zu 255 Zeichen. Es steht in der Regelliste und in Support-Gesprächen. Wird nie ausgewertet.
AktiviertAusgeschaltet bleibt die Regel erhalten, wird aber gar nicht ausgewertet — sie trifft auf nichts zu und liefert keinen Score.
PhaseAnfrage — die Regel wird ausgewertet, bevor die Anfrage an den Origin weitergereicht wird.
ÜbereinstimmungAlle Bedingungen (UND) oder Beliebige Bedingung (ODER). Standard: alle.
ReihenfolgeAufsteigend, kleinere Zahl zuerst. Jede Regel sollte eine eigene Zahl bekommen — bei gleicher Reihenfolge ist die Abfolge offen.
BedingungenEine oder mehrere Bedingungszeilen: Ziele, Operator, Muster, optional Transformationen, optional Negieren.
AktionWas bei einem Treffer geschieht, samt den Parametern, die diese Aktion braucht.

Reihenfolge ist eine Zahl, die selbst vergeben wird. Lücken (10, 20, 30) machen es leicht, später eine Regel dazwischenzuschieben.


Bedingungen

Eine Bedingung stellt genau eine Frage an die Anfrage: diese Teile der Anfrage nehmen, optional bereinigen und mit diesem Operator gegen dieses Muster prüfen.

Ziele — was geprüft wird

Ein Ziel liefert eine Liste von Werten. Mehrwertige Ziele fächern auf, und der Operator läuft gegen jeden Wert einzeln — deshalb bringt es einem Angreifer nichts, zusätzliche Query-Parameter zu streuen.

ZielLiefertAnmerkungen
uriden AnfragepfadBereits prozentdekodiert und normalisiert. Ohne Query-String.
uri.rawPfad und Query, unverändertGenau so, wie der Client sie geschickt hat, ohne Dekodierung. Das einzige Ziel, das Kodierungstricks übersteht — siehe erstes Beispiel.
queryden rohen Query-StringAlles nach dem ?, weiterhin URL-kodiert, als ein Wert.
argsjeden Wert eines Query-ParametersDekodiert. Wiederholte Parameter fächern auf. Nur Query-String — Formularfelder stehen hier nicht.
args.namesjeden Namen eines Query-ParametersFängt Parameternamen-Sondierungen und Prototype-Pollution-Versuche ab.
headersjeden Header-Wert der AnfrageAlle. Ein wiederholter Header fächert auf.
headers.user-agentden Wert dieses Headers
headers.refererden Wert dieses Headers
headers.hostden Wert dieses Headers
headers.content-typeden Wert dieses Headers
cookiesjeden Cookie-WertCookie-Namen lassen sich nicht prüfen.
body.rawden gesamten AnfragekörperEin Wert, beliebiger Content-Type — auch multipart, das sonst nicht zerlegt wird.
body.formjeden Formularfeld-WertNur bei Content-Type x-www-form-urlencoded.
body.jsonjeden Blattwert des JSONRekursiv, maximale Tiefe 32. Nur wenn der Content-Type json enthält. Schlüssel werden nicht erfasst, nur Blätter.
ipdie Client-IPDie echte Besucheradresse, nicht ein Proxy-Zwischenschritt. Siehe Client-IP.
methoddie HTTP-MethodeGroßgeschrieben, z. B. POST.
hostden Host der Anfrage
geoip.countryden ISO-LändercodeLeer, wenn nicht auflösbar.
geoip.asndie AS-NummerNumerisch. 0, wenn unbekannt. Mit einem numerischen Operator oder within kombinieren.

Eine Bedingung darf mehrere Ziele aufführen. Sie ist wahr, sobald irgendein Wert irgendeines aufgeführten Ziels den Operator besteht.

INFO

Anfragekörper werden nur unter Bedingungen geprüft. Ein body.*-Ziel sieht nur dann Daten, wenn die Methode POST, PUT, PATCH oder DELETE lautet, die Content-Length höchstens 256 KB beträgt und der Körper im Arbeitsspeicher geblieben ist. Ein großer Upload wird stillschweigend übergangen — eine Body-Regel deckt also keine Datei-Uploads ab.

Transformationen — die Schicht gegen Verschleierung

Transformationen laufen auf jedem ausgelesenen Wert, von links nach rechts in der angegebenen Reihenfolge, bevor der Operator ihn zu sehen bekommt. Angreifer weichen viel häufiger über Kodierung aus als über neue Nutzlasten. Hier entsteht deshalb der größte Teil der Robustheit.

TransformationWas sie machtBeispiel
lowercaseSetzt den Wert in Kleinbuchstaben. Für ASCII verlässlich.UNIONunion
uppercaseSetzt den Wert in Großbuchstaben.abcABC
urlDecodeDekodiert %XX und macht aus + ein Leerzeichen.%2e%2e%2f../
urlDecodeUniLöst zuerst %uXXXX im IIS-Stil auf, danach die Prozentkodierung. Codepoints ab 256 entfallen.%u003cscript<script
htmlEntityDecodeLöst &#NN;, &#xHH; sowie die benannten Entitäten lt gt amp quot apos nbsp auf. Unbekannte Namen bleiben stehen.&lt;script&gt;<script>
base64DecodeDekodiert Base64. Schlägt das fehl, geht der ursprüngliche Wert unverändert weiter — der Einsatz auf Verdacht ist also gefahrlos.c2VsZWN0select
normalizePathFasst mehrfache Schrägstriche zusammen und löst . und .. auf. Dekodiert nicht vorher — urlDecode davorsetzen./a/./b/../c/a/c
removeNullsEntfernt \0-Bytes, den klassischen Trick zum Zerteilen von Filtern.ad\0minadmin
removeWhitespaceEntfernt jedes Leerraumzeichen.UNION SELECTUNIONSELECT
compressWhitespaceFasst jede Folge von Leerraum zu einem einzelnen Leerzeichen zusammen und erhält damit die Wortgrenzen.UNION SELECTUNION SELECT
lengthErsetzt den Wert durch seine Zeichenanzahl. Gehört zu einem numerischen Operator. Bei einem mehrwertigen Ziel ist das die Länge jedes einzelnen Werts, nicht die Anzahl der Werte.abcd4

TIP

Ein vernünftiger Standardsatz. Für die Inhaltsprüfung auf args, body.* oder uri: urlDecoderemoveNullslowercase. Für XSS kommt htmlEntityDecode dazu, für Path-Traversal normalizePath. Die Reihenfolge zählt: erst dekodieren, dann normalisieren, dann kleinschreiben.

Operatoren — wie verglichen wird

Operator (Beschriftung)WertBedeutungFormat des Musters
Entspricht RegexrxPCRE-Ausdruck, Teiltreffer ohne Verankerung. Groß-/Kleinschreibung zählt, solange nicht (?i) oder lowercase dazukommt.(?i)union\s+select
SQL-Injection erkennendetectSQLiDer SQL-Injection-Detektor von libinjection — dieselbe Bibliothek, die auch die großen Open-Source-WAFs einsetzen.keins
XSS erkennendetectXSSDer XSS-Detektor von libinjection.keins
EnthältcontainsWörtliche Teilzeichenkettensuche, keine Regex-Auswertung. Groß-/Kleinschreibung zählt.Zeichenkette
Gleich (Zeichenkette)streqExakte Gleichheit. Groß-/Kleinschreibung zählt.Zeichenkette
Beginnt mitbeginsWithWörtlicher Präfixtest.Zeichenkette
Endet mitendsWithWörtlicher Suffixtest. Ein leeres Muster trifft nie zu.Zeichenkette
Entspricht einer PhrasepmDer Wert enthält eines der aufgeführten Literale. Gedacht für lange Stichwortlisten.durch Leerraum getrennt: sqlmap nikto nmap
Ist in Menge enthaltenwithinDer Wert ist gleich einem Element der Menge.durch Leerraum oder Komma getrennt: GET, HEAD
IP entsprichtipMatchLiest den Wert als IP und prüft ihn gegen eine Menge aus Adressen und CIDRs. IPv4 und IPv6.10.0.0.0/8, 2001:db8::/32
≥  >  ≤  <  = (numerisch)ge gt le lt eqBeide Seiten werden als Zahl gelesen; ein nicht numerischer Wert auf einer Seite ergibt schlicht falsch. Passt zu length oder geoip.asn.eine Zahl, z. B. 2048

WARNING

Die Falle mit der Groß-/Kleinschreibung. Entspricht Regex erzwingt keine Unabhängigkeit von der Schreibweise — das entscheidet die Regel. Fast jeder Fehlschlag einer handgeschriebenen Regel kommt daher, dass union select dort steht und UnIoN SeLeCt daran vorbeigeht. Also (?i)union\s+select schreiben oder die Transformation lowercase ergänzen.

Ein fehlerhaftes Muster bringt nie die Anfrage zu Fall: die Bedingung wird dann einfach falsch.

Bedingungen verknüpfen

Übereinstimmung legt fest, wie die Bedingungszeilen zusammenwirken:

  • Alle Bedingungen — jede Zeile muss wahr sein (UND).
  • Beliebige Bedingung — mindestens eine Zeile muss wahr sein (ODER).

Verschachtelung gibt es nicht und auch keinen Operator pro Zeile: eine flache Liste, eine Verknüpfung. Für alles Komplexere wird die Logik auf zwei Regeln aufgeteilt.

WARNING

Negieren kehrt die ganze Bedingung um, nicht jeden einzelnen Wert. Bei einem mehrwertigen Ziel bedeutet Negieren kein Wert hat getroffen — nicht irgendein Wert hat nicht getroffen. Eine negierte Bedingung auf args ist falsch, sobald ein einziger Parameter zutrifft.

Genau dieses Verhalten ist zugleich die einzige Möglichkeit, auf Abwesenheit zu prüfen. Ein Ziel ohne Inhalt liefert eine leere Liste, also kann nichts den Operator bestehen und die Bedingung ist falsch; mit eingeschaltetem Negieren wird sie wahr:

Ziele:     headers.referer
Operator:  Entspricht Regex
Muster:    .
Negieren:  ein
→ wahr, wenn die Anfrage überhaupt keinen Referer-Header trägt

Aktionen

AktionAm EdgeBeendet die Anfrage?Braucht
BlockierenLiefert die Sicherheitsseite der Zone mit 403 und bricht ab.jaAntwort-Status
ChallengeLiefert das JavaScript-Proof-of-Work-Interstitial. Wer bereits einen gültigen Nachweis hat, kommt direkt durch.außer bei gültigem Nachweis
DrosselnBremst die Anfrage, ohne sie abzulehnen. Sie läuft weiter zu Cache und Origin.neinRate und/oder Verzögerung
ÜberspringenÜbernimmt die Entscheidung für diese Anfrage, sodass keine spätere WAF-Regel mehr handeln kann, und vermerkt skip.nein
ProtokollierenHält den Treffer fest und handelt nicht — übernimmt aber ebenfalls die Entscheidung. Siehe die Warnung unten.nein
ScoreErhöht den Anomalie-Score der Anfrage und lässt die Auswertung weiterlaufen. Die einzige wirklich passive Aktion.neinScore

Blockieren

Eine blockierte Anfrage wird mit 403 und der Sicherheitsseite der Zone beantwortet, die sich unter Benutzerdefinierte Seiten im eigenen Design gestalten lässt.

Score und die Anomalie-Schwelle

Score entscheidet für sich genommen nichts. Der Wert kommt zu einer laufenden Summe für die Anfrage hinzu, und wenn keine Regel die Entscheidung übernommen hat und die Summe 5 erreicht, wird die Anfrage blockiert. Die Schwelle liegt fest bei 5 und ist pro Zone nicht einstellbar.

Das ist das Mittel für Signale, die verdächtig, aber für sich allein nicht beweiskräftig sind — ein Skript-User-Agent, ein fehlendes Accept-Language, eine ungewöhnliche Methode. Keines davon rechtfertigt eine Blockade; drei davon zusammen unter Umständen schon.

Der Score wird bei jeder Aktion addiert, nicht nur bei Score. Eine blockierende Regel darf also zusätzlich einen Score tragen, damit der Treffer in der Gesamtsumme der Anfrage auftaucht.

Drosseln

Drosseln hat zwei Hebel, und sie treffen unterschiedliche Störenfriede:

  • Rate (Bytes/s) begrenzt den Durchsatz des Antwortkörpers. Der Hebel gegen bandbreitenhungrige Scraper. 0 heißt keine Begrenzung.
  • Verzögerung (ms) legt eine einmalige Pause ein, bevor die Anfrage Cache oder Origin erreicht, gedeckelt bei 5000 ms. Der Hebel gegen Bots mit vielen kleinen Anfragen, bei denen ein winziger Antwortkörper jede Ratenbegrenzung wirkungslos macht.

Mindestens einer der beiden Werte muss ungleich null sein. Drosseln mehrere Quellen dieselbe Anfrage, setzt sich die stärkste durch: die größte Verzögerung und die kleinste Rate ungleich null.

Überspringen

Überspringen nimmt eine Anfrage vom Rest der WAF-Regelliste aus — auch von den verwalteten Regeln von Smoxy, die sonst greifen würden. Eine niedrige Reihenfolge sorgt dafür, dass die Regel zuerst läuft.

Die vorgelagerten Sicherheitsstufen macht sie nicht rückgängig. Reputationsverdikte, Under Attack Mode und die IP-Listen sind bereits angewandt, wenn die Engine läuft; um eine Anfrage davon auszunehmen, braucht es eine Access Rule mit Allow oder Skip.

WARNING

Protokollieren ist nicht passiv. Die Aktion hält den Treffer fest und handelt selbst nicht, sie übernimmt aber die Entscheidung — jede spätere Regel, die blockiert hätte, kommt damit nicht mehr zum Zug, und auch die Anomalie-Schwelle bleibt außen vor.

Für passives Beobachten, das späteren Regeln den Vortritt lässt, eignet sich Score mit dem Wert 0. Der Treffer wird trotzdem festgehalten und bleibt im Traffic-Log sichtbar.


Wie über eine Anfrage entschieden wird

Über das Ergebnis entscheidet die Reihenfolge, nicht die Schwere. Eine Challenge mit Reihenfolge 10 schlägt eine Blockade mit Reihenfolge 20.

  1. Die eigenen Regeln und die von Smoxy verwalteten Regeln werden zu einer Liste zusammengeführt und aufsteigend nach Reihenfolge sortiert.
  2. Jede Regel wird der Reihe nach ausgewertet. Deaktivierte Regeln werden übersprungen.
  3. Bei einem Treffer kommt der Score der Regel zur laufenden Summe hinzu — bei jeder Aktion, nicht nur bei Score.
  4. Die erste zutreffende Regel, deren Aktion nicht Score ist, übernimmt den einen Entscheidungsplatz. Spätere Regeln dürfen weiterhin Score beisteuern, die Entscheidung aber nicht mehr ändern.
  5. Hat nach der Liste nichts die Entscheidung übernommen und die angesammelte Summe 5 erreicht, wird die Anfrage blockiert.
  6. Das Verdikt wird bei jeder Anfrage festgehalten, ob getroffen oder nicht — siehe Prüfen, ob eine Regel gegriffen hat.

Kurz: genau eine Regel entscheidet. Alles andere steuert Score bei oder kommt zu spät.


Von Smoxy verwaltete Regeln

Regeln unter Von Smoxy verwaltete Regeln stammen von smoxy, werden dort gepflegt und gelten plattformweit — etwa gegen das Absuchen nach Konfigurationsdateien, gegen Tor-Exit-Knoten oder gegen zu aggressive Crawler. Bearbeiten lassen sie sich nicht; über den Schalter in der Zeile lässt sich jede einzelne für die eigene Zone ein- oder ausschalten.

Die Kennzeichnungen in der Zeile zeigen, wie eine Regel die Zone erreicht:

  • Verwaltet — die Regel gehört smoxy, nicht der Zone.
  • Opt-in — die Regel ist für die Zone aus, bis sie eingeschaltet wird. Regeln ohne diese Kennzeichnung sind standardmäßig an und bleiben es, bis sie ausgeschaltet werden.

Eine ausdrückliche Entscheidung schlägt immer den Standard und bleibt erhalten: Ändert smoxy später den Standard einer Regel, behält eine Zone, die sich schon festgelegt hat, ihre Wahl.

Eine verwaltete Regel ausschalten

Den Schalter der Zeile umlegen. Die Regel greift für die Zone sofort nicht mehr — sie blockiert nicht, prüft nicht per Challenge, drosselt nicht und fließt auch nicht mehr in die Anomalie-Schwelle ein.

Ausgewertet wird sie weiterhin. Eine für die Zone ausgeschaltete Regel fließt in einen getrennten Shadow-Score ein, der im Traffic-Log als waf_rule_action = shadow auftaucht. So bleibt sichtbar, ob sie gegriffen hätte — und ein Opt-out lässt sich anhand von Belegen zurücknehmen statt nach Gefühl.

TIP

Verwaltete Regeln bleiben am besten an, solange nicht nachweislich eine davon Fehlalarme für die eigene Anwendung auslöst. Im Zweifel zuerst ins Traffic-Log schauen oder den Support fragen.


Prüfen, ob eine Regel gegriffen hat

Jede Anfrage trägt das Verdikt der Regel-Engine, ob etwas getroffen hat oder nicht. Die Werte stehen im Traffic-Log der Zone und stehen als Antwort-Header zur Verfügung, sobald die Debug-Header für die Zone aktiv sind.

Antwort-HeaderFeld im Traffic-LogBedeutung
s-waf-rulewaf_ruleDie ID der Regel, die entschieden hat, oder score, wenn die Anomalie-Schwelle ausgelöst hat.
s-waf-rule-actionwaf_rule_actionblock, challenge, throttle, skip, log oder shadow.
s-waf-rule-scorewaf_rule_scoreDer Anomalie-Score der Anfrage, einschließlich des Shadow-Scores nicht durchgesetzter Regeln.

WARNING

Zwei Verdikte, ähnliche Namen. waf_action und waf_score gehören nicht zur Regel-Engine — sie tragen das IP-Reputationsverdikt der verwalteten Szenarien. Eine von einer eigenen WAF-Regel blockierte Anfrage zeigt regelmäßig waf_action: allow direkt neben waf_rule_action: block.

Bei der Untersuchung einer WAF-Regel zählt waf_rule_action.

s-allowlist erzählt die umgekehrte Geschichte: Der Wert benennt die Vertrauensliste, die eine Anfrage komplett an der Engine vorbeigeführt hat (global, tenant oder verified_bot). Bleibt eine erwartete Regel wirkungslos, lohnt hier der erste Blick.


Beispiele

Beispiel 1: eine Dateisuche, versteckt in einem Tracking-Parameter

Aus dem laufenden Betrieb. Eine Anfrage sah aus wie eine gewöhnliche Produktseite:

/fahrrad-bekleidung/…/castelli-espresso-2-w-radtrikot-kurzarm-damen-kaufen.html
  ?srsltid=AfmBOoovzZW4ddo…jwWUE/.env.development

An einen echten Google-Parameter srsltid war hinten eine Suche nach .env angehängt. Das Ziel uri hätte das nicht gesehen — uri endet vor dem ?. Genau dafür gibt es uri.raw.

Beschreibung:  Suche nach Umgebungs- und Konfigurationsdateien blockieren
Übereinstimmung: Beliebige Bedingung
Reihenfolge:   10
Bedingung:     Ziele            uri.raw
               Transformationen urlDecode, lowercase
               Operator         Entspricht einer Phrase
               Muster           .env .git/config wp-config.php .aws/credentials id_rsa
Aktion:        Blockieren

Beispiel 2: SQL-Injection, ohne Regex

SQL-Injection erkennen braucht kein Muster — der Operator lässt einen eigens dafür gebauten Detektor über jeden Wert laufen.

Beschreibung:  SQL-Injection in Query und Formulardaten blockieren
Übereinstimmung: Beliebige Bedingung
Reihenfolge:   20
Bedingung 1:   Ziele            args, body.form
               Transformationen urlDecode, removeNulls
               Operator         SQL-Injection erkennen
Bedingung 2:   Ziele            body.json
               Transformationen removeNulls
               Operator         SQL-Injection erkennen
Aktion:        Blockieren

Beispiel 3: verdächtige Automatisierung bewerten statt blockieren

Keines der beiden Signale rechtfertigt für sich eine Blockade. Zusammen mit allem Weiteren, was Score liefert, reißen sie die Schwelle.

Beschreibung:  Anomalie-Score für Skript-Clients erhöhen
Übereinstimmung: Beliebige Bedingung
Reihenfolge:   200
Bedingung 1:   Ziele            headers.user-agent
               Transformationen lowercase
               Operator         Entspricht einer Phrase
               Muster           curl wget python-requests go-http-client libwww-perl
Bedingung 2:   Ziele            headers.user-agent
               Operator         Entspricht Regex
               Muster           ^$
Aktion:        Score
Score:         3

Beispiel 4: einen Scraper bremsen, ohne ihn zu blockieren

Beschreibung:  Massenhaftes Abgrasen des Katalogs drosseln
Übereinstimmung: Alle Bedingungen
Reihenfolge:   50
Bedingung 1:   Ziele            uri
               Operator         Beginnt mit
               Muster           /catalog/
Bedingung 2:   Ziele            geoip.asn
               Operator         Ist in Menge enthalten
               Muster           14061, 16509, 24940
Aktion:        Drosseln
Rate:          65536
Verzögerung:   250

Die ASNs von Hosting-Anbietern sind für einen Shop-Katalog ein starkes Signal: Echte Kundschaft stöbert selten aus einem Rechenzentrum.

Beispiel 5: einen Endpunkt ausnehmen, der die Regeln auslöst

Ein Webhook-Empfänger mit ungewöhnlichen Nutzdaten kann aussehen wie ein Angriff. Eine niedrige Reihenfolge stellt sicher, dass die Ausnahme vor allem anderen läuft.

Beschreibung:  WAF-Regeln für den Zahlungs-Webhook überspringen
Übereinstimmung: Alle Bedingungen
Reihenfolge:   0
Bedingung 1:   Ziele            uri
               Transformationen normalizePath, lowercase
               Operator         Gleich (Zeichenkette)
               Muster           /webhooks/payment
Bedingung 2:   Ziele            ip
               Operator         IP entspricht
               Muster           203.0.113.0/24
Aktion:        Überspringen

Der Pfad gehört mit einer Herkunftsprüfung zusammen. Eine skip-Regel allein auf dem Pfad ist eine offene Tür mit der eigenen Adresse daran.

Beispiel 6: einen verwundbaren Endpunkt sperren, bis der Patch steht

Ein virtueller Patch verschafft die Zeit, den echten Fix auszurollen.

Beschreibung:  CVE-2026-31887 — Durchprobieren von Bestellcodes blockieren
Übereinstimmung: Alle Bedingungen
Reihenfolge:   5
Bedingung 1:   Ziele            uri
               Transformationen urlDecode, normalizePath, lowercase
               Operator         Beginnt mit
               Muster           /store-api/order
Bedingung 2:   Ziele            method
               Operator         Gleich (Zeichenkette)
               Muster           POST
Bedingung 3:   Ziele            body.json
               Operator         Entspricht Regex
               Muster           ^[a-f0-9]{32}$
Aktion:        Blockieren

Regeln über die API verwalten

Jedes Feld des Editors steht auch über die API zur Verfügung, dazu einige, die die Oberfläche nicht zeigt.

MethodeEndpunktZweck
GET/api/zones/{zoneId}/security/waf-rulesEigene Regeln der Zone auflisten
POST/api/zones/{zoneId}/security/waf-rulesRegel anlegen
GET/api/zones/{zoneId}/security/waf-rules/{id}Eine Regel lesen
PATCH/api/zones/{zoneId}/security/waf-rules/{id}Regel ändern
DELETE/api/zones/{zoneId}/security/waf-rules/{id}Regel löschen
GET/api/zones/{zoneId}/security/global-waf-rulesDie für die Zone geltenden verwalteten Regeln auflisten
PATCH/api/zones/{zoneId}/security/global-waf-rules/{id}Eine verwaltete Regel für die Zone ein- oder ausschalten

Die Regel für Skript-Clients aus Beispiel 3 anlegen:

bash
curl -X POST "https://api.smoxy.eu/api/zones/412/security/waf-rules" \
  -H "Authorization: Bearer $SMOXY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "description": "Anomalie-Score für Skript-Clients erhöhen",
    "enabled": true,
    "phase": "request",
    "order": 200,
    "match": "any",
    "conditions": [
      {
        "targets": ["headers.user-agent"],
        "transforms": ["lowercase"],
        "operator": "pm",
        "pattern": "curl wget python-requests go-http-client libwww-perl"
      },
      {
        "targets": ["headers.user-agent"],
        "operator": "rx",
        "pattern": "^$"
      }
    ],
    "action": "score",
    "score": 3
  }'

Eine verwaltete Regel für eine Zone ausschalten:

bash
curl -X PATCH "https://api.smoxy.eu/api/zones/412/security/global-waf-rules/550e8400-e29b-41d4-a716-446655440000" \
  -H "Authorization: Bearer $SMOXY_TOKEN" \
  -H "Content-Type: application/merge-patch+json" \
  -d '{"enabledForZone": false}'

Zur Authentifizierung siehe API-Token.

Felder, die die Oberfläche nicht zeigt

FeldWirkung
stopBeendet die Regelauswertung vollständig, sobald die Regel greift — spätere Regeln steuern nicht einmal mehr Score bei. Bei verwalteten Regeln, die für die Zone aus sind, ohne Wirkung.
expressionEin Notausgang für Logik, die die Bedingungsliste nicht abbildet, in derselben Ausdruckssprache wie bei den Access Rules. Wird nur ausgewertet, wenn conditions leer ist.

Validierung

Die API weist eine Regel zurück, die eine dieser Vorgaben verletzt:

  • Mindestens eine Bedingung oder eine expression.
  • Jede Bedingung hat ein nicht leeres targets-Array und einen bekannten operator.
  • Jeder Operator außer detectSQLi und detectXSS hat ein nicht leeres pattern.
  • action: block trägt einen status zwischen 100 und 599.
  • action: throttle trägt ein rateBps und/oder delayMs ungleich null.
  • Ziele und Transformationen stammen aus den Listen auf dieser Seite.

Gut zu wissen

  • Es entscheidet die Reihenfolge, nicht die Schwere. Die erste zutreffende Regel, die nicht Score ist, gewinnt. Ausnahmen gehören an den Anfang des Zahlenbereichs, Blockaden dahinter, und jede Regel bekommt eine eigene Zahl.
  • Protokollieren und Überspringen legen spätere Regeln still. Nur Score ist passiv.
  • Regex achtet auf Groß-/Kleinschreibung, solange nicht (?i) oder lowercase etwas anderes vorgibt.
  • Erst dekodieren, dann vergleichen. Eine Regel ohne Transformationen ist ein %2e%2e%2f davon entfernt, nutzlos zu sein.
  • uri ist normalisiert, uri.raw nicht. Bei der Suche nach eingeschmuggelten Nutzlasten gehören beide geprüft.
  • Körper über 256 KB werden nicht geprüft. Bei GET ebenso wenig.
  • Eine Regel kann keine frühere Entscheidung aufheben. Adressen auf der Allowlist, verifizierte Crawler und Ausnahmen per Access Rule erreichen die Engine gar nicht.
  • Blockaden antworten mit 403. Die Seite dazu lässt sich unter Benutzerdefinierte Seiten gestalten.
  • Neue Regeln zuerst mit Score: 0 fahren. Eine neue Regel passiv ausrollen, einen Tag lang waf_rule im Traffic-Log beobachten und sie danach auf die gewünschte Aktion umstellen.

Weiterführend