# 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.