rate_limiting.md 2.9 KB

Rate Limiting

Zweck

Schützt die API gegen Spam, Bot-Traffic und Missbrauch durch zu viele Anfragen in kurzer Zeit.

Implementierung

  • Klasse: src/security/ratelimiter.php
  • Strategie: Sliding-Window auf Basis von Zeitstempeln
  • Persistenz: Flat Files in storage/rate_limit/
  • Schlüsselablage: pro Key wird sha256(key).json verwendet
  • Sperren: flock(LOCK_EX) je Key-Datei

Konfiguration

In config/app.local.php:

  • rate_limit.enabled Globaler Schalter (true/false). Bei false lässt der Limiter alle Requests durch.
  • rate_limit.requests Maximal erlaubte Requests pro Zeitfenster
  • rate_limit.window_seconds Länge des Zeitfensters in Sekunden

Default:

  • enabled = true
  • requests = 30
  • window_seconds = 300 (5 Minuten)

Aktuell geschützte Endpunkte

  • POST /api/request-otp.php
    • Key: otp-request:{ip}:{email}
  • POST /api/verify-otp.php
    • Key: otp-verify:{ip}:{email}
  • POST /api/load-draft.php
    • Key: load:{ip}:{email}
  • POST /api/save-draft.php
    • Key: save:{ip}:{email}
  • POST /api/submit.php
    • Key: submit:{ip}:{email}
  • POST /api/reset.php
    • Key: reset:{ip}:{email}
  • POST /api/upload-preview.php
    • Key: preview-upload:{ip}:{email}
  • POST /api/delete-upload.php
    • Key: delete-upload:{ip}:{email}

Hinweis: Jeder Endpunkt hat einen eigenen Prefix und damit ein separates Limit-Fenster.

Kapazität bei aktivem Limiting

Aktive Konfiguration (config/app.local.php):

  • enabled = true
  • requests = 30
  • window_seconds = 300 (5 Minuten)

Daraus ergibt sich pro Rate-Limit-Bucket (Key = prefix + ip + email):

  • 5 Minuten: 30 Requests
  • 1 Stunde: 360 Requests
  • 24 Stunden: 8.640 Requests

Da aktuell 8 Endpunkte getrennte Buckets nutzen, ist der theoretische Gesamtwert über alle Endpunkte (gleiche IP + E-Mail) entsprechend:

  • 5 Minuten: 240 Requests
  • 1 Stunde: 2.880 Requests
  • 24 Stunden: 69.120 Requests

Verhalten bei Limitüberschreitung

API antwortet mit HTTP 429 und einer Fehlermeldung (z. B. „Zu viele Anfragen“).

Betriebsaspekte

  • Viele Dateien in storage/rate_limit/ sind normal.
  • Verzeichnis muss für den Webserver beschreibbar sein.
  • Löschen einzelner Dateien setzt das Limit für den betreffenden Key zurück.
  • Komplettes Leeren des Ordners setzt alle Limits zurück.

Tuning-Empfehlungen

  • Höherer Schutz: requests senken oder window_seconds erhöhen.
  • Weniger strenger Schutz: requests erhöhen oder window_seconds senken.
  • Bei aggressiven Bot-Wellen zuerst submit härter setzen (ggf. zukünftig endpoint-spezifische Limits einführen).

Bekannte Eigenschaften

  • Bei Dateisystemproblemen (Datei kann nicht geöffnet/gesperrt werden) erlaubt der Limiter aktuell die Anfrage (fail-open), um legitime Nutzer nicht zu blockieren.
  • NAT/Shared-IP kann mehrere legitime Nutzer unter derselben IP bündeln; durch Kombination mit E-Mail ist das Risiko reduziert.