Files
breadcrumb-the-shire/docs/howto-anfragelimits.md
fs 545bcc789b docs: replace ASCII umlaut fallbacks with proper äöüß across all .md
Most German docs were written with `ue`/`ae`/`oe`/`ss` ASCII fallbacks
(`fuer`, `aenderung`, `koennen`, `gemaess`) — relic from older toolchain
constraints. Replaced 237 occurrences across 38 .md files with proper
umlauts and ß so the docs read naturally.

Substitutions are constrained to plain prose: fenced code blocks
(```...```), inline code spans (`...`), markdown link targets `[..](..)`,
and HTML comments are preserved verbatim. Path references like
`docs/howto-erste-aenderung.md` keep their original (umlaut-replaced)
filenames — only the surrounding prose is normalised.

Tool: bin/fix-md-umlauts.py (idempotent — no-op on already-clean files).
Re-runnable if ASCII fallbacks creep back in via copy-paste.

Doc-link-check + doc-drift-check stay green.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-29 09:57:22 +02:00

82 lines
2.1 KiB
Markdown

# Anfragelimits (Rate Limiting)
Letzte Aktualisierung: 2026-03-14
## Ziel
Brute-Force und API-Spam begrenzen, ohne Verfügbarkeit zu gefährden.
## Technischer Kern
- Service: `core/Service/Security/RateLimiterService.php`
- Repository: `core/Repository/Security/RateLimitRepository.php`
- Storage: `request_rate_limits`
- `scope`, `subject_hash`, `hits`, `window_started_at`, `blocked_until`
Wichtig:
- Subject wird gehasht (SHA-256), kein Klartext-Key.
- Verhalten ist fail-open bei Storage-Fehlern.
## API-Limits (global)
Durchgesetzt in `core/Http/ApiBootstrap.php`:
1. IP-only (`api.ip`)
- 120 Requests / 60s
- Block 120s
2. Token+IP (`api.token_ip`)
- 300 Requests / 60s
- Block 120s
Bei Block:
- HTTP `429`
- `Retry-After`
- Body `{"error":"rate_limit_exceeded"}`
## Web-Login-Limits
In `pages/auth/login().php`:
1. Resolve-Phase pro IP (`login.resolve.ip`)
- 25 Versuche / 600s
- Block 300s
2. Passwortphase pro E-Mail+IP (`login.password.email_ip`)
- 5 Fehlversuche / 900s
- Block 900s
Erfolgreicher Passwort-Login setzt den Passwort-Scope zurück.
## API-Login-Limits
In `pages/api/v1/auth/login().php` (zusätzlich zu globalen API-Limits):
1. IP (`api.auth.login.ip`)
- 10 Fehlversuche / 600s
- Block 300s
2. E-Mail+IP (`api.auth.login.email_ip`)
- 5 Fehlversuche / 900s
- Block 900s
Erfolgreicher API-Login setzt `api.auth.login.email_ip` zurück.
## Remember-Token-Limits
In `core/Service/Auth/RememberMeRateLimiter.php` (Memcached-basiert):
1. Pro IP (`remember_rl:{ip}`)
- 5 Fehlversuche / 900s
- Block 900s (automatisch via Memcached-TTL)
Erfolgreicher Auto-Login setzt den Counter zurück.
Unterschied zu den DB-basierten Limits oben: Memcached statt `request_rate_limits`-Tabelle. Verhindert DB-Last bei Brute-Force gegen Remember-Cookies.
## Smoke-Test
1. API ohne Token >120 Requests/min gegen `/api/v1/*` -> `429` erwartet.
2. Web-Login mit falschem Passwort >5 pro E-Mail+IP -> `429` erwartet.
3. API-Login mit falschen Credentials wiederholt -> `429` erwartet.
4. Remember-Cookie mit falschem Token >5 pro IP -> Auto-Login blockiert, Cookie gelöscht.