Zum Hauptinhalt springen

Einführung

CSRF (Cross-Site Request Forgery) ist ein Angriff, bei dem sich der Angreifer als eingeloggter Benutzer ausgibt und diesen ungewollte Anfragen absenden lässt. Angenommen, Ihre Anwendung stellt POST /user/email bereit und akzeptiert damit E-Mail-Adressänderungen. Wenn ein Angreifer auf einer anderen Website ein Formular platziert, das diese URL automatisch aufruft, könnte die E-Mail-Adresse eines Nutzers geändert werden, ohne dass er es bemerkt. In Laravel 13 ist der CSRF-Schutz durch die in der Middleware-Gruppe web enthaltenen Mechanismen standardmäßig aktiv.

Verhinderung von CSRF-Angriffen

Die Middleware PreventRequestForgery von Laravel schützt in zwei Schichten vor CSRF:
  1. Origin-Prüfung (Header Sec-Fetch-Site)
  2. Token-Prüfung (CSRF-Token pro Session)
Zuerst wird der Origin geprüft; wenn keine Entscheidung möglich ist oder die Prüfung fehlschlägt, wird auf die Token-Prüfung zurückgegriffen.

Origin-Prüfung

Laravel prüft zunächst Sec-Fetch-Site und stellt fest, ob die Anfrage vom selben Origin stammt. Das ist besonders in HTTPS-Umgebungen wirksam. Besteht die Anfrage die Origin-Prüfung, wird sie direkt zugelassen. Andernfalls wird wie bisher die CSRF-Token-Prüfung ausgeführt.
Sec-Fetch-Site setzt eine HTTPS-Verbindung voraus. In HTTP-Umgebungen funktioniert die Origin-Prüfung nicht, sodass die Token-Prüfung den Hauptschutz bildet.

Origin-only-Modus

Sie können das Fallback auf die Token-Prüfung deaktivieren und die Entscheidung nur anhand der Origin-Prüfung treffen.
use Illuminate\Foundation\Application;
use Illuminate\Foundation\Configuration\Middleware;

return Application::configure(basePath: dirname(__DIR__))
    ->withMiddleware(function (Middleware $middleware): void {
        $middleware->preventRequestForgery(originOnly: true);
    });
Im Origin-only-Modus liefern Anfragen, die die Origin-Prüfung nicht bestehen, statt 419 den Statuscode 403. Möchten Sie Same-Site-Anfragen zulassen (z. B. zwischen Subdomains), setzen Sie allowSameSite.
$middleware->preventRequestForgery(allowSameSite: true);

Token-Prüfung

Laravel erzeugt pro Session ein CSRF-Token. Sie erhalten es über csrf_token() oder aus der Session.
use Illuminate\Http\Request;

Route::get('/token', function (Request $request) {
    $tokenFromSession = $request->session()->token();
    $tokenFromHelper = csrf_token();
});
Wenn Sie unter web-Routen Formulare mit POST, PUT, PATCH oder DELETE erstellen, binden Sie stets @csrf ein.
<form method="POST" action="/profile">
    @csrf

    <!-- Entspricht dem folgenden hidden Input -->
    <input type="hidden" name="_token" value="{{ csrf_token() }}" />
</form>

URIs ausschließen

Bei Anfragen von externen Diensten, etwa Webhooks von Stripe, ist es manchmal nötig, bestimmte URIs vom CSRF-Schutz auszunehmen.
use Illuminate\Foundation\Application;
use Illuminate\Foundation\Configuration\Middleware;

return Application::configure(basePath: dirname(__DIR__))
    ->withMiddleware(function (Middleware $middleware): void {
        $middleware->preventRequestForgery(except: [
            'stripe/*',
            'http://example.com/foo/bar',
            'http://example.com/foo/*',
        ]);
    });
Wenn möglich, legen Sie Webhook-Routen außerhalb der Middleware-Gruppe web ab und halten Sie die Ausschlussliste minimal.

X-CSRF-TOKEN-Header

Laravel prüft nicht nur das Feld _token aus dem Formular, sondern auch den Header X-CSRF-TOKEN. Geben Sie das Token zunächst in einem Meta-Tag aus.
<meta name="csrf-token" content="{{ csrf_token() }}">
Fügen Sie dessen Wert dem Header Ihrer AJAX-Requests hinzu.
$.ajaxSetup({
    headers: {
        'X-CSRF-TOKEN': document
            .querySelector('meta[name="csrf-token"]')
            .getAttribute('content'),
    },
});

X-XSRF-TOKEN-Header

Laravel setzt zusätzlich ein verschlüsseltes XSRF-TOKEN-Cookie. Axios und Angular übernehmen diesen Wert bei Same-Origin-Anfragen automatisch in den Header X-XSRF-TOKEN. Dadurch greift der CSRF-Schutz in SPA- oder AJAX-Implementierungen häufig, ohne dass Sie den Header manuell setzen müssen.

Überlegungen bei SPAs

Wenn Sie Laravel als API-Backend für eine SPA einsetzen, holen Sie zuerst das CSRF-Cookie und senden anschließend die Login-Anfrage.
await axios.get('/sanctum/csrf-cookie');
await axios.post('/login', {
    email: '[email protected]',
    password: 'password',
});
Weitere Details finden Sie unter Sanctum.
Zuletzt geändert am 13. Juli 2026