Auto-commit: 2026-05-22 14:42
This commit is contained in:
59
memory/gitea-specs/issue-42.md
Normal file
59
memory/gitea-specs/issue-42.md
Normal file
@@ -0,0 +1,59 @@
|
||||
# Issue #42 – CSRF-Schutz für Kontaktformular
|
||||
|
||||
## Komplexität: S (Small)
|
||||
- Token-Generierung, Hidden-Field, Validierung
|
||||
- Geschätzter Aufwand: < 30 Min
|
||||
|
||||
## Analyse
|
||||
Kontaktformular in HomeController. Session wird bereits gestartet. CSRF-Token muss vor Formular-Render generiert und bei POST validiert werden.
|
||||
|
||||
### Aktueller Formular-Flow
|
||||
1. `session_start()` in HomeController::index()
|
||||
2. POST-Verarbeitung mit Validierung
|
||||
3. Redirect nach Verarbeitung (PRG-Pattern)
|
||||
4. Session speichert Formular-Status
|
||||
|
||||
### Architektur-Entscheidung
|
||||
CSRF-Token direkt in HomeController implementieren:
|
||||
1. Token beim GET-Request generieren und in Session speichern
|
||||
2. Token als Hidden-Field im Formular ausgeben
|
||||
3. Bei POST: Token validieren bevor Verarbeitung
|
||||
|
||||
### Implementierung
|
||||
```php
|
||||
// GET: Token generieren
|
||||
if (empty($_SESSION['csrf_token'])) {
|
||||
$_SESSION['csrf_token'] = bin2hex(random_bytes(32));
|
||||
}
|
||||
|
||||
// POST: Token validieren
|
||||
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||
$csrfToken = $_POST['csrf_token'] ?? '';
|
||||
if (!hash_equals($_SESSION['csrf_token'] ?? '', $csrfToken)) {
|
||||
// CSRF-Fehler
|
||||
header('Location: /#form-result');
|
||||
exit;
|
||||
}
|
||||
// ... bestehende Validierung
|
||||
}
|
||||
```
|
||||
|
||||
Im View: `<input type="hidden" name="csrf_token" value="<?= htmlspecialchars($_SESSION['csrf_token'] ?? '') ?>">`
|
||||
|
||||
### Akzeptanzkriterien
|
||||
- [ ] CSRF-Token wird bei jedem GET generiert
|
||||
- [ ] Token ist als Hidden-Field im Formular vorhanden
|
||||
- [ ] POST ohne gueltiges Token wird abgelehnt
|
||||
- [ ] Formular funktioniert weiterhin korrekt mit Token
|
||||
|
||||
### Abhängigkeiten
|
||||
Keine. Unabhaengig von anderen Issues.
|
||||
|
||||
### Edge Cases
|
||||
- Token muss nach erfolgreicher Validierung nicht regeneriert werden (kein Login-Kontext)
|
||||
- Mehrere Tabs: Gleicher Token pro Session ist ok
|
||||
- Honeypot-Feld: Muss vor CSRF-Check kommen (sonst CSRF-Fehler beim Bot-Trap)
|
||||
|
||||
### Sicherheitsrisiken
|
||||
- `hash_equals()` statt `===` verwenden (timing-safe Vergleich)
|
||||
- Token-Laenge: 64 Hex-Zeichen (32 Bytes) ausreichend
|
||||
Reference in New Issue
Block a user