CSRF protectie is een beveiliging dat niet iedereen via andere websites een POST kan doen op formulieren van jou website. Dit geeft meer veiligheid tegen hackers.
Alle ins en outs over CSRF protectie kan je hier lezen.
We gaan onze eigen CSRF protectie inbouwen in onze site. Daarvoor moeten we bij elke POST request een controle doen of deze van onze site afkomstig is. Dit doen we door aan elk formulier een de volgende code toe te voegen
<form method="post"> <?= csrf() ?> ... </form>
We gaan een nieuw bestand maken csrf.php en voegen een require toe aan index.php. Let op dat je dit doet nadat de functions.php wordt toegevoegd.
//csrf protectie require "csrf.php";
Dit bestand krijgt twee nieuwe functies. Een functie om de token te maken en toe te voegen aan het formulier. En een functie om te kijken of een meegestuurde token geldig is.
//valideren van een token
//valideren van een token function validateToken(): bool { if (in_array($_POST['_token'] ?? '', $_SESSION['tokens'] ?? [])) { $_SESSION['tokens'] = []; //alle tokens wissen, zodat ze niet hergebruikt kunnen worden return true; } if (isset($_SERVER['HTTP_X_CSRF_TOKEN'])) { if ($_SERVER['HTTP_X_CSRF_TOKEN'] == ($_SESSION['api_token'] ?? "")) { return true; } } return false; } //aanmaken van een token voor je formulier function csrf($field = true): string { $bytes = random_bytes(256); $token = bin2hex($bytes); $_SESSION['tokens'][] = $token; if ($field) { return "<input type=\"hidden\" name=\"_token\" value=\"$token\">"; } else { return $token; } }
Dit bestand doet een controle of er een POST is en roept de valideer functie aan.
Indien niet geldig zal het script de gebruiker een 401 error geven.
<?php //CSRF protection if ($_POST != null) { if (!validateToken()) { http_response_code(401); $error = "CSRF-token mismatch error."; require "view/401.view.php"; die(); } }
Voeg een view/401.view.php toe met bijvoorbeeld onderstaande code
<?php require "parts/header.view.php"; require "parts/menu.view.php"; ?> <!-- hier de about pagina --> <div class="mx-auto max-w-7xl py-20 sm:px-6 lg:px:8"> <h1 class="text-2xl font-bold mb-4">401 Geen toegang: <?= $error ?? '' ?></h1> <p class="mt-2"> <a href="/" class="text-indigo-800 hover:text-indigo-600">Ga terug naar home</a> </p> </div> <?php require "parts/footer.view.php";
Nu kan je de CSRF protectie makkelijk aan en uit zetten door wel of niet in je index een // voor require "csrf.php" te zetten
//csrf protectie //require "csrf.php";