1.9 KiB
1.9 KiB
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
session_start()in HomeController::index()- POST-Verarbeitung mit Validierung
- Redirect nach Verarbeitung (PRG-Pattern)
- Session speichert Formular-Status
Architektur-Entscheidung
CSRF-Token direkt in HomeController implementieren:
- Token beim GET-Request generieren und in Session speichern
- Token als Hidden-Field im Formular ausgeben
- Bei POST: Token validieren bevor Verarbeitung
Implementierung
// 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