- Inledning
- Förhindra CSRF-begäranden
- Exkludera URI:er
- X-CSRF-Token
- X-XSRF-Token
Introduktion
Förfalskningar av förfrågningar på olika webbplatser är en typ av skadlig exploatering där obehöriga kommandon utförs för en autentiserad användares räkning. Tack och lov gör Laravel det enkelt att skydda din applikation från CSRF-attacker (cross-site request forgery).
En förklaring av sårbarheten
Om du inte är bekant med cross-site request forgeries ska vi diskutera ett exempel på hur denna sårbarhet kan utnyttjas. Föreställ dig att ditt program har en /user/email
-väg som accepterar en POST
-förfrågan om att ändra den autentiserade användarens e-postadress. Troligtvis förväntar sig den här rutten att ett email
inmatningsfält ska innehålla den e-postadress som användaren vill börja använda.
Och utan CSRF-skydd kan en skadlig webbplats skapa ett HTML-formulär som pekar på din applikations /user/email
-väg och skickar in den skadegörande användarens egen e-postadress:
<form action="https://your-application.com/user/email" method="POST"> <input type="email" value=""></form><script> document.forms.submit();</script>
Om den skadegörande webbplatsen automatiskt skickar in formuläret när sidan laddas behöver den skadegörande användaren bara locka en intet ont anande användare av din applikation till att besöka deras webbplats, så kommer deras e-postadress att ändras i din applikation.
För att förhindra den här sårbarheten måste vi inspektera varje inkommande POST
, PUT
, PATCH
eller DELETE
-begäran för att hitta ett hemligt sessionsvärde som det skadliga programmet inte har tillgång till.
Förhindra CSRF-begäranden
Laravel genererar automatiskt en CSRF-”token” för varje aktiv användarsession som hanteras av programmet. Denna token används för att verifiera att den autentiserade användaren är den person som faktiskt gör förfrågningar till programmet. Eftersom denna token lagras i användarens session och ändras varje gång sessionen återskapas kan ett skadligt program inte komma åt den.
Den aktuella sessionens CSRF-token kan nås via sessionen för begäran eller via hjälpfunktionen csrf_token
:
use Illuminate\Http\Request;Route::get('/token', function (Request $request) { $token = $request->session()->token(); $token = csrf_token(); // ...});
Varje gång du definierar ett HTML-formulär i ditt program bör du inkludera ett dolt CSRF _token
-fält i formuläret så att CSRF-skyddets middleware kan validera begäran. För enkelhetens skull kan du använda @csrf
Blade-direktivet för att generera det dolda inmatningsfältet för token:
<form method="POST" action="/profile"> @csrf <!-- Equivalent to... --> <input type="hidden" name="_token" value="{{ csrf_token() }}" /></form>
Middelfunktionen App\Http\Middleware\VerifyCsrfToken
, som ingår i gruppen web
middleware som standard, verifierar automatiskt att tokenet i inmatningsfältet för begäran stämmer överens med tokenet som lagras i sessionen. När dessa två token matchar vet vi att det är den autentiserade användaren som initierar begäran.
CSRF-token & SPAs
Om du bygger en SPA som använder Laravel som API-backend bör du konsultera Laravel Sanctum-dokumentationen för att få information om autentisering med ditt API och skydd mot CSRF-sårbarheter.
Exkludera URI:er från CSRF-skydd
Ibland vill du kanske utesluta en uppsättning URI:er från CSRF-skydd. Om du till exempel använder Stripe för att hantera betalningar och använder deras webhook-system måste du utesluta din Stripe-webhook-hanteringsrutt från CSRF-skydd eftersom Stripe inte vet vilken CSRF-token som ska skickas till dina rutter.
Typiskt sett bör du placera den här typen av rutter utanför web
-mellanvarugruppen som App\Providers\RouteServiceProvider
tillämpar på alla rutter i routes/web.php
-filen. Du kan dock också utesluta vägarna genom att lägga till deras URI:er i egenskapen $except
för VerifyCsrfToken
middleware:
<?phpnamespace App\Http\Middleware;use Illuminate\Foundation\Http\Middleware\VerifyCsrfToken as Middleware;class VerifyCsrfToken extends Middleware{ /** * The URIs that should be excluded from CSRF verification. * * @var array */ protected $except = ;}
{tip} För enkelhetens skull inaktiveras CSRF-mellanvaran automatiskt för alla vägar när du kör tester.
X-CSRF-TOKEN
För att kontrollera CSRF-token som en POST-parameter kontrollerar App\Http\Middleware\VerifyCsrfToken
-mellanvaran även X-CSRF-TOKEN
-förfrågningshuvudet. Du kan till exempel lagra token i en HTML meta
-tagg:
<meta name="csrf-token" content="{{ csrf_token() }}">
Därefter kan du instruera ett bibliotek som jQuery att automatiskt lägga till tokenet i alla förfrågningshuvuden. Detta ger ett enkelt och bekvämt CSRF-skydd för dina AJAX-baserade program som använder äldre JavaScript-teknik:
$.ajaxSetup({ headers: { 'X-CSRF-TOKEN': $('meta').attr('content') }});
X-XSRF-TOKEN
Laravel lagrar den aktuella CSRF-token i en krypterad XSRF-TOKEN
-cookie som ingår i varje svar som genereras av ramverket. Du kan använda kakans värde för att ställa in X-XSRF-TOKEN
-förfrågningshuvudet.
Den här kakan skickas främst som en bekvämlighet för utvecklare eftersom vissa JavaScript-ramverk och bibliotek, som Angular och Axios, automatiskt placerar dess värde i X-XSRF-TOKEN
-huvudet på förfrågningar med samma ursprung.