Sessions und CSRF-Schutz in PHP – Formulare gegen Fremdzugriff absichern
Ein Login ohne CSRF-Schutz lässt sich von fremden Seiten missbrauchen. Ich zeige dir das Token-Muster, das jedes Formular absichert – erzeugen, verstecktes Feld, per hash_equals prüfen – plus die richtigen Session-Cookie-Einstellungen.
Sobald ein PHP-Formular etwas verändert (Login, Speichern, Löschen), braucht es einen CSRF-Schutz. Ohne ihn könnte eine fremde Website deinen eingeloggten Nutzer heimlich ein Formular absenden lassen. Das Gegenmittel ist ein geheimes Token pro Session.
Session sicher starten
<?php
declare(strict_types=1);
session_set_cookie_params([
'httponly' => true, // kein Zugriff per JavaScript (schützt vor XSS-Diebstahl)
'samesite' => 'Lax', // Cookie nicht bei fremden Cross-Site-Requests senden
'secure' => true, // nur über HTTPS
]);
session_start();Token erzeugen und ins Formular legen
function csrf_token(): string
{
if (empty($_SESSION['csrf'])) {
$_SESSION['csrf'] = bin2hex(random_bytes(32));
}
return $_SESSION['csrf'];
}
?>
<form method="post" action="/speichern.php">
<input type="hidden" name="csrf" value="<?= htmlspecialchars(csrf_token()) ?>">
<!-- weitere Felder -->
<button type="submit">Speichern</button>
</form>Beim Absenden prüfen
function check_csrf(): void
{
$sent = $_POST['csrf'] ?? '';
if (!is_string($sent) || !hash_equals($_SESSION['csrf'] ?? '', $sent)) {
http_response_code(419);
exit('Sitzung abgelaufen. Bitte lade die Seite neu.');
}
}Zwei Details sind wichtig: random_bytes liefert ein kryptografisch sicheres Token (nicht rand()), und hash_equals vergleicht zeitkonstant – ein normaler ===-Vergleich könnte über minimale Zeitunterschiede angreifbar sein.
Ruf check_csrf() ganz am Anfang jedes POST-Handlers auf, bevor irgendetwas gespeichert wird. Genau dieses Muster steckt auch im Admin-Backend, das ich für meine Kunden baue. Mehr auf bymw.de.
Quellen
Du brauchst mehr als ein Snippet?
Ich entwickle Android-Apps in Kotlin und moderne Websites für Selbstständige und kleine Unternehmen — von der ersten Idee bis zum Release.
Projekt anfragen →Verwandte Snippets
array_find, array_any und array_all in PHP 8.4 – Arrays durchsuchen ohne Schleife
„Gibt es einen inaktiven Eintrag?", „Sind alle bezahlt?", „Hol mir den ersten Treffer" – dafür hast du bisher eine foreach-Schleife mit break geschrieben. PHP 8.4 macht daraus je eine Zeile, die genau sagt, was sie meint.
First-Class-Callable-Syntax in PHP: aus strlen(...) wird ein echter Wert
Funktionen als Zeichenketten weiterzureichen – 'strlen', [$objekt, 'methode'] – hat nie jemand gemocht: kein Tippfehlerschutz, keine Sprungmarke in der IDE. Seit PHP 8.1 schreibst du drei Punkte und bekommst ein Closure-Objekt.
Dateirechte verstehen – was 755 und 644 wirklich bedeuten
chmod 777 löst jedes Rechteproblem – und schafft ein größeres. Die drei Ziffern sind kein Zauberspruch, sondern eine simple Addition. Wer sie einmal verstanden hat, rät nie wieder.