CSRF: Was ist das und wie verhindern Sie es?
CSRF (Cross-Site-Request-Forgery, websiteübergreifende Anfragenfälschung) bedeutet, dass der Browser eines angemeldeten Benutzers ohne dessen Wissen dazu gebracht wird, eine Anfrage an Ihre Website zu senden. Der Browser fügt jeder Anfrage an Ihre Website von selbst die Cookies dieser Website hinzu. Besucht der Benutzer eine andere Seite, während er bei Ihnen angemeldet ist, kann diese Seite den Browser eine Anfrage an Ihre Website stellen lassen, und die Anfrage wird mit der Sitzung des Benutzers verarbeitet.
Die Folge: Jede Aktion, die der Benutzer ausführen darf, kann in seinem Namen ausgeführt werden, etwa die E-Mail-Adresse ändern, Datensätze löschen oder im Administrationsbereich einen neuen Benutzer anlegen. Der Angreifer sieht die Antwort nicht; das Ziel ist nicht, Daten zu lesen, sondern eine Aktion auszulösen. Die Lösung besteht darin zu prüfen, ob die Anfrage tatsächlich von Ihrer eigenen Seite stammt.
Kurz gefasst
- Bei CSRF wird der Browser eines angemeldeten Benutzers ohne dessen Wissen zu einer Anfrage gebracht.
- Der eigentliche Schutz ist ein CSRF-Token in jedem Formular, das auf dem Server geprüft wird.
- SameSite-Cookie und Origin-Prüfung sind zusätzliche Schichten.
- Aktionen, die einen Zustand ändern, werden nicht per GET ausgeführt.
Auf dieser Seite
Wie funktioniert CSRF, und wo wird es gestoppt?
-
Der Browser sendet das Cookie von selbst
Die Ursache des Problems ist, dass der Server die Anfrage allein anhand des Sitzungs-Cookies akzeptiert. Weil das Cookie bei jeder Anfrage von selbst mitgeschickt wird, kann der Server nicht unterscheiden, ob der Benutzer die Anfrage aus eigenem Antrieb gestellt hat oder ob sie von einer anderen Website ausgelöst wurde.
: Vergrößern -
Das Token beweist, dass die Anfrage von Ihrer Seite stammt
Ein CSRF-Token ist ein vom Server erzeugter, an die Sitzung gebundener, nicht erratbarer Zufallswert. Es wird als verstecktes Feld in Ihre Formulare eingefügt und beim Eintreffen der Anfrage auf dem Server geprüft. Da eine andere Website diesen Wert nicht kennen kann, wird die von ihr ausgelöste Anfrage abgelehnt.
: Vergrößern -
Die Schichten ergänzen einander
Das Token ist der eigentliche Schutz. Das Cookie-Attribut
SameSitebietet zusätzlichen Schutz auf Browserebene; die Prüfung desOrigin-Headers fügt eine dritte Kontrolle hinzu; und dass Aktionen, die einen Zustand ändern, nicht per GET ausgeführt werden, ist die Voraussetzung dafür, dass diese Schutzmaßnahmen überhaupt greifen.
: Vergrößern
Anzeichen: Woran erkennt man das Problem?
- Im Code-Review: Fehlt in Formularen, die Daten ändern, das versteckte Token-Feld oder prüft der Server dieses Feld nicht, gibt es keinen Schutz. Werden Aktionen wie Löschen, Freigeben oder Statusänderungen über einen Link (GET) ausgeführt, ist die Schwachstelle sicher vorhanden.
- Im Browser: Sehen Sie sich in den Entwicklertools das Attribut
SameSitedes Sitzungs-Cookies an; ist es nicht gesetzt oder steht es aufNone, fehlt der zusätzliche Schutz. - Bei den Benutzern: Geänderte Einstellungen, von denen der Benutzer sagt, er habe sie nicht vorgenommen, sowie Datensätze, die in seinem Namen angelegt oder gelöscht wurden.
- In den Protokollen: Bei Anfragen, die einen Zustand ändern, steht in
RefereroderOrigineine Adresse, die nichts mit Ihrer Website zu tun hat.
Umsetzung des CSRF-Tokens
Das Token wird einmal pro Sitzung erzeugt, in der Sitzung gespeichert und in jedem Formular als verstecktes Feld mitgesendet. Der Vergleich erfolgt mit hash_equals; diese Funktion verhindert, dass über Laufzeitunterschiede Informationen abfließen.
<?php
session_start();
function csrfBelirteci(): string
{
if (empty($_SESSION['csrf'])) {
$_SESSION['csrf'] = bin2hex(random_bytes(32));
}
return $_SESSION['csrf'];
}
function csrfDogrula(?string $gelen): bool
{
return is_string($gelen)
&& !empty($_SESSION['csrf'])
&& hash_equals($_SESSION['csrf'], $gelen);
}Verwendung im Formular:
<form method="post" action="profil-guncelle">
<input type="hidden" name="csrf" value="<?= htmlspecialchars(csrfBelirteci(), ENT_QUOTES, 'UTF-8') ?>">
<label for="eposta">E-Mail</label>
<input type="email" id="eposta" name="eposta" required>
<button type="submit">Speichern</button>
</form>Prüfen Sie das Token bei der Verarbeitung der Anfrage, bevor Sie irgendetwas anderes tun:
<?php
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
http_response_code(405);
header('Allow: POST');
echo 'Diese Aktion ist nur über das Absenden des Formulars möglich.';
return;
}
if (!csrfDogrula($_POST['csrf'] ?? null)) {
http_response_code(403);
echo 'Ihre Sitzung konnte nicht bestätigt werden. Laden Sie die Seite neu und versuchen Sie es erneut.';
return;
}
// ... Prüfung bestanden: Aktion ausführenDarauf sollten Sie achten:
- Schreiben Sie das Token nicht in die URL; über die Adresszeile, die Protokolle und den
Referer-Header kann es nach außen gelangen. - Erneuern Sie bei der Anmeldung zusammen mit der Sitzungs-ID auch das Token.
- Schützen Sie auch das Anmeldeformular selbst; andernfalls kann ein Benutzer unbemerkt im Konto einer anderen Person angemeldet werden.
- Frameworks wie Laravel und Symfony sowie die meisten Content-Management-Systeme bringen einen fertigen CSRF-Schutz mit; nutzen Sie diesen, statt eine eigene Lösung zu schreiben, und schalten Sie ihn nicht ab.
AJAX- und API-Anfragen
Bei Anfragen, die per JavaScript gesendet werden, wird das Token in der Regel aus einem meta-Tag gelesen und in einem eigenen Anfrage-Header mitgeschickt. Der Server prüft den Wert aus dem Header auf dieselbe Weise.
// In der Seite: <meta name="csrf" content="...vom Server erzeugtes Token...">
var belirtec = document.querySelector('meta[name="csrf"]').content;
fetch('sepet/ekle', {
method: 'POST',
headers: { 'Content-Type': 'application/json', 'X-CSRF-Token': belirtec },
credentials: 'same-origin',
body: JSON.stringify({ urun: 12, adet: 1 })
});
// Auf dem Server: csrfDogrula($_SERVER['HTTP_X_CSRF_TOKEN'] ?? null)Bei APIs, die die Identität nicht über ein Cookie, sondern über ein Token prüfen, das bei jeder Anfrage im Authorization-Header gesendet wird, ist das CSRF-Risiko ein anderes, weil der Browser die Zugangsdaten nicht von selbst hinzufügt. Jeder Endpunkt, der Cookies verwendet, muss dagegen geschützt werden.
Das Cookie-Attribut SameSite
SameSite legt fest, ob das Cookie bei Anfragen mitgesendet wird, die von anderen Websites ausgehen:
- Strict: Das Cookie wird nur bei Anfragen mitgesendet, die von derselben Website ausgehen. Das ist die sicherste Variante; kommt der Benutzer jedoch von einer anderen Website (z. B. über einen Link in einer E-Mail), ist seine Sitzung bei der ersten Anfrage nicht sichtbar.
- Lax: Das Cookie wird bei einer Top-Level-Navigation von einer anderen Website (Klick auf einen Link) mitgesendet, nicht aber bei POST-Anfragen, die von einer anderen Website ausgehen. Für die meisten Websites ist das der passende Kompromiss.
- None: Das Cookie wird bei jeder Anfrage mitgesendet; es muss zusammen mit
Secureverwendet werden. Gedacht ist das nur für Cookies, die tatsächlich im Drittanbieter-Kontext funktionieren müssen.
<?php
// Sitzungs-Cookie (vor session_start)
session_set_cookie_params([
'lifetime' => 0,
'path' => '/',
'secure' => true,
'httponly' => true,
'samesite' => 'Lax',
]);
session_start();
// Ihre eigenen Cookies
setcookie('tercih', 'koyu', [
'expires' => time() + 60 * 60 * 24 * 30,
'path' => '/',
'secure' => true,
'httponly' => true,
'samesite' => 'Lax',
]);Viele aktuelle Browser behandeln Cookies ohne dieses Attribut wie Lax; verlassen Sie sich aber nicht darauf und geben Sie den Wert ausdrücklich an. SameSite allein gilt nicht als ausreichend: Lax schützt keine Zustandsänderungen, die per GET erfolgen, und wird eine Ihrer Subdomains übernommen, gilt sie als „dieselbe Website“. Verwenden Sie das Attribut zusammen mit dem Token.
Origin- und Referer-Prüfung
Browser fügen POST-Anfragen, die von einer anderen Quelle ausgehen, den Origin-Header hinzu. Bei Anfragen, die einen Zustand ändern, zu prüfen, ob dieser Header zu Ihrer eigenen Domain passt, ist eine zusätzliche Kontrolle neben dem Token. Fehlt der Header, kann der Wert von Referer herangezogen werden; fehlen beide, überlassen Sie die Entscheidung der Token-Prüfung.
<?php
function ayniKaynak(): bool
{
$kaynak = $_SERVER['HTTP_ORIGIN'] ?? ($_SERVER['HTTP_REFERER'] ?? '');
if ($kaynak === '') {
return true; // kein Header: Die Entscheidung bleibt der Token-Prüfung überlassen
}
$gelen = strtolower((string) parse_url($kaynak, PHP_URL_HOST));
$izinli = ['www.example.com', 'example.com']; // Ihre eigenen Domains
return in_array($gelen, $izinli, true);
}
if ($_SERVER['REQUEST_METHOD'] === 'POST' && !ayniKaynak()) {
http_response_code(403);
echo 'Die Anfrage wurde nicht akzeptiert.';
return;
}Kein GET für Aktionen, die einen Zustand ändern
GET-Anfragen dürfen Daten nur lesen. Werden Aktionen wie Löschen, Freigeben, Bestellen oder das Ändern von Einstellungen über einen Link der Form ?aktion=loeschen&id=5 ausgeführt, kann jede beliebige Seite, die diese Adresse enthält, die Aktion auslösen; außerdem können auch Suchmaschinen-Bots und die Vorabladefunktion des Browsers solchen Links folgen.
- Wandeln Sie solche Aktionen in ein kleines POST-Formular um; soll es wie ein Link aussehen, lässt sich die Schaltfläche per CSS gestalten.
- Prüfen Sie auf dem Server die Anfragemethode; lehnen Sie GET ab, wo POST erwartet wird.
- Auch die Abmeldung muss per POST erfolgen.
<!-- FALSCH: <a href="kayit-sil?id=5">Löschen</a> -->
<form method="post" action="kayit-sil">
<input type="hidden" name="csrf" value="<?= htmlspecialchars(csrfBelirteci(), ENT_QUOTES, 'UTF-8') ?>">
<input type="hidden" name="id" value="<?= (int) $kayit['id'] ?>">
<button type="submit">Löschen</button>
</form>Erneute Bestätigung bei kritischen Aktionen
Fordern Sie bei kritischen Aktionen wie der Änderung von Passwort oder E-Mail-Adresse, der Aktualisierung von Zahlungsdaten oder dem Anlegen eines Administrators erneut das aktuelle Passwort oder den Code der Zwei-Faktor-Authentifizierung an. Diese Maßnahme wirkt sowohl gegen CSRF als auch gegen den Missbrauch offen gelassener Sitzungen.
Bedenken Sie: Gibt es auf Ihrer Website eine XSS-Schwachstelle, kann das Skript des Angreifers das Token auf der Seite auslesen und den CSRF-Schutz überwinden. Betrachten Sie beide Schutzmaßnahmen gemeinsam.
Häufige Fehler
- Das Token erzeugen, aber nicht prüfen: Im Formular gibt es das versteckte Feld, der Server vergleicht den Wert aber nicht. Der Schutz steckt in der Zeile mit der Prüfung.
- Einen leeren Wert akzeptieren: Gibt es in der Sitzung kein Token, ergibt der Vergleich eines leeren eingehenden Wertes mit einem leeren Wert „gleich“. Prüfen Sie, dass beide Seiten gefüllt sind.
- Nur einige Formulare schützen: Kleine Aktionen im Administrationsbereich wie Löschen, Sortieren oder Statusänderungen werden vergessen. Der Schutz gehört nicht in einzelne Formulare, sondern an eine zentrale Stelle, die für alle POST-Anfragen gilt.
- Das Token im Cookie ablegen und nur das Cookie prüfen: Das Cookie wird ohnehin bei jeder Anfrage von selbst mitgesendet; der Vergleichswert muss aus dem Formular oder aus einem Anfrage-Header stammen.
- Eine GET-Anfrage wie POST verarbeiten: Code, der
$_REQUESTverwendet, akzeptiert auch Parameter, die per GET eintreffen. Prüfen Sie die Anfragemethode ausdrücklich und lesen Sie die Daten aus$_POST. - JSON-Endpunkte vergessen: Die Annahme „Diese Adresse wird nur von JavaScript aufgerufen“ ist kein Schutz; jeder Endpunkt, der die Identität über ein Cookie prüft, muss ein Token verlangen.
- Im Fehlerfall weitermachen: Schlägt die Prüfung fehl, muss die Anfrage dort enden; eine Warnung anzuzeigen und die Aktion trotzdem auszuführen, macht den Schutz sinnlos.
Checkliste
- Jedes Formular, das Daten ändert, enthält ein CSRF-Token, das auf dem Server mit
hash_equalsgeprüft wird. - AJAX-Anfragen senden das Token in einem Header.
- Auch An- und Abmeldung sind geschützt.
- Keine Aktion, die einen Zustand ändert, wird per GET ausgeführt.
- Das Sitzungs-Cookie hat
SameSite=LaxoderStrictsowieSecureundHttpOnly. - Die Origin-Prüfung ist als zusätzliche Schicht umgesetzt.
- Bei kritischen Aktionen wird das Passwort oder der zweite Faktor erneut abgefragt.
- Der fertige CSRF-Schutz des Frameworks ist aktiv; Adressen, für die Ausnahmen definiert sind, wurden durchgesehen.
Häufige Fragen
Ich verwende SameSite=Lax; brauche ich trotzdem ein Token?
Ja. SameSite ist eine starke zusätzliche Schicht, schützt aber keine Änderungen, die per GET erfolgen, kann in alten Browsern fehlen, und Ihre Subdomains gelten als „dieselbe Website“. Verwenden Sie es zusammen mit dem Token.
Worin unterscheiden sich CSRF und XSS?
Bei XSS läuft das Skript des Angreifers auf Ihrer Seite. Bei CSRF läuft kein Skript; der Browser des Benutzers wird dazu gebracht, von einer anderen Website aus eine Anfrage an Ihre Website zu senden. Eine XSS-Schwachstelle kann auch den CSRF-Schutz überwinden.
Soll ich für jedes Formular ein eigenes Token erzeugen?
Ein einziges Token pro Sitzung genügt für die meisten Websites und bereitet bei der Zurück-Schaltfläche oder bei mehreren Tabs keine Probleme. Ein Token, das bei jeder Anfrage erneuert wird, ist strenger, erschwert aber die Bedienung.
Verhindert ein Captcha CSRF?
Es erschwert CSRF indirekt, ist aber nicht dafür gedacht und lässt sich nicht in jedem Formular einsetzen. Das richtige Werkzeug gegen CSRF ist das Token.
BYK Yazılım Support-Team
Diese Anleitung wird vom Support-Team von BYK Yazılım erstellt und regelmäßig überprüft. Letzte Aktualisierung: 04.10.2026.
Verwandte Anleitungen
- XSS: Was ist das und wie verhindern Sie es?Kontextgerechtes Ausgabe-Escaping, Content-Security-Policy, HttpOnly-Cookie und die Bereinigung von Rich Text.
- Login- und SitzungssicherheitPasswort-Hashing, Begrenzung der Anmeldeversuche, Session-Fixation, Cookie-Flags und Berechtigungsprüfung bei jeder Anfrage.
- Sicherheitsheader und HTTPSHSTS, CSP, X-Content-Type-Options, Referrer-Policy und Permissions-Policy; mit .htaccess-Beispiel.
- Leitfaden zur Website-Sicherheit: Wo anfangen?Bedrohungsarten, mehrschichtige Verteidigung, Prioritäten und ein Wegweiser zu allen Sicherheitsanleitungen.
Sehen wir uns Ihre Website gemeinsam an
BYK Yazılım entwickelt Unternehmenswebsites. Schreiben Sie uns, wenn Sie Fragen zu Ihrer Website haben.
Kontakt aufnehmen Unsere Leistung: Unternehmenswebsite