diff --git a/includes/csrf.php b/includes/csrf.php new file mode 100644 index 0000000..db0575e --- /dev/null +++ b/includes/csrf.php @@ -0,0 +1,88 @@ +'; +} + +/** + * Prüft, ob das per POST gesendete CSRF-Token zum Session-Token passt. + * + * Der Vergleich erfolgt zeitkonstant über hash_equals(), um + * Timing-Angriffe auf den Vergleich selbst auszuschließen. + * + * @return bool true, wenn das Token gültig ist + */ +function csrf_verify(): bool +{ + $sentToken = $_POST["csrf_token"] ?? ""; + $sessionToken = $_SESSION["csrf_token"] ?? ""; + + if (!is_string($sentToken) || $sentToken === "" || $sessionToken === "") { + return false; + } + + return hash_equals($sessionToken, $sentToken); +} + +/** + * Bricht die Anfrage ab und leitet mit einer Fehlermeldung um, + * wenn das mitgesendete CSRF-Token ungültig oder nicht vorhanden ist. + * + * Muss am Anfang jeder zustandsändernden POST-Aktion aufgerufen werden, + * bevor irgendeine Änderung an Daten vorgenommen wird. + * + * @param string $redirectTo Ziel-URL, zu der bei ungültigem Token + * weitergeleitet wird + * @return void + */ +function csrf_require_valid(string $redirectTo = "index.php"): void +{ + if (!csrf_verify()) { + http_response_code(403); + $_SESSION["message"] = "invalid_csrf_token"; + header("Location: " . $redirectTo); + exit(); + } +} \ No newline at end of file