login.php erzeugte expires_at mit PHPs date(), verify_2fa.php verglich
gegen MySQLs NOW(). Webserver (secureserver.net) und Datenbankserver
(mysql2fda.netcup.net) liegen bei verschiedenen Anbietern und sind
unabhaengig voneinander konfiguriert. Laeuft PHP in UTC und MySQL in
Europe/Berlin, liegt expires_at (PHP-Zeit + 5 Minuten) zwei Stunden
vor NOW() - jeder Code gilt sofort als abgelaufen und wird als
"Falscher oder abgelaufener Code" abgewiesen.
Die Ablaufzeit wird jetzt beim INSERT per DATE_ADD(NOW(), INTERVAL 5
MINUTE) berechnet. Erzeugung und Pruefung benutzen damit dieselbe Uhr,
unabhaengig davon, wie die beiden Server eingestellt sind.
Ausserdem:
- Der eingegebene Code wird auf Ziffern reduziert. Aus HTML-Mails
kopierte Codes schleppen oft Leerzeichen oder geschuetzte
Leerzeichen mit, die den Hash-Vergleich scheitern liessen.
- Abgelaufener Code und falscher Code werden getrennt gemeldet, damit
ein solcher Fall kuenftig ohne Raten eingegrenzt werden kann.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>