- Wprowadzenie
- Zapobieganie żądaniom CSRF
- Wykluczanie URIs
- X-CSRF-Token
- X-XSRF-Token
Wprowadzenie
Cross-site request forgeries są rodzajem złośliwego exploita, w którym nieautoryzowane polecenia są wykonywane w imieniu uwierzytelnionego użytkownika. Na szczęście Laravel ułatwia ochronę twojej aplikacji przed atakami CSRF (cross-site request forgery).
Wyjaśnienie podatności
W przypadku, gdy nie jesteś zaznajomiony z cross-site request forgery, omówmy przykład wykorzystania tej podatności. Wyobraź sobie, że twoja aplikacja posiada trasę /user/email
, która akceptuje żądanie POST
zmiany adresu e-mail uwierzytelnionego użytkownika. Najprawdopodobniej trasa ta oczekuje, że pole wejściowe email
będzie zawierało adres e-mail, którego użytkownik chciałby zacząć używać.
Bez ochrony CSRF złośliwa witryna mogłaby utworzyć formularz HTML, który wskazywałby na trasę /user/email
Twojej aplikacji i przesyłałby własny adres e-mail złośliwego użytkownika:
<form action="https://your-application.com/user/email" method="POST"> <input type="email" value=""></form><script> document.forms.submit();</script>
Jeśli złośliwa witryna automatycznie przesyła formularz podczas ładowania strony, złośliwy użytkownik musi tylko zwabić niczego niepodejrzewającego użytkownika Twojej aplikacji do odwiedzenia swojej witryny, a jego adres e-mail zostanie zmieniony w Twojej aplikacji.
Aby zapobiec tej luce, musimy sprawdzać każde przychodzące żądanie POST
, PUT
, PATCH
lub DELETE
pod kątem tajnej wartości sesji, do której złośliwa aplikacja nie ma dostępu.
Preventing CSRF Requests
Laravel automatycznie generuje „token” CSRF dla każdej aktywnej sesji użytkownika zarządzanej przez aplikację. Ten token jest używany do weryfikacji, że uwierzytelniony użytkownik jest osobą faktycznie wykonującą żądania do aplikacji. Ponieważ ten token jest przechowywany w sesji użytkownika i zmienia się za każdym razem, gdy sesja jest regenerowana, złośliwa aplikacja nie jest w stanie uzyskać do niego dostępu.
Dostęp do tokena CSRF bieżącej sesji można uzyskać za pośrednictwem sesji żądania lub za pomocą funkcji pomocniczej csrf_token
:
use Illuminate\Http\Request;Route::get('/token', function (Request $request) { $token = $request->session()->token(); $token = csrf_token(); // ...});
Za każdym razem, gdy definiujesz formularz HTML w swojej aplikacji, powinieneś zawrzeć ukryte pole CSRF _token
w formularzu, aby oprogramowanie pośredniczące ochrony CSRF mogło zatwierdzić żądanie. Dla wygody możesz użyć dyrektywy @csrf
Blade, aby wygenerować ukryte pole wejściowe tokena:
<form method="POST" action="/profile"> @csrf <!-- Equivalent to... --> <input type="hidden" name="_token" value="{{ csrf_token() }}" /></form>
Oprogramowanie pośredniczące App\Http\Middleware\VerifyCsrfToken
, które domyślnie znajduje się w grupie oprogramowania pośredniczącego web
, automatycznie zweryfikuje, czy token w danych wejściowych żądania pasuje do tokena przechowywanego w sesji. Kiedy te dwa tokeny pasują do siebie, wiemy, że uwierzytelniony użytkownik jest tym, który inicjuje żądanie.
CSRF Tokens & SPA
Jeśli budujesz SPA, które wykorzystuje Laravel jako backend API, powinieneś zapoznać się z dokumentacją Laravel Sanctum, aby uzyskać informacje na temat uwierzytelniania z API i ochrony przed podatnościami CSRF.
Wykluczanie URI z ochrony CSRF
Czasami możesz chcieć wykluczyć zestaw URI z ochrony CSRF. Na przykład, jeśli używasz Stripe do przetwarzania płatności i korzystasz z ich systemu webhook, będziesz musiał wykluczyć swoją trasę obsługi webhook Stripe z ochrony CSRF, ponieważ Stripe nie będzie wiedział, jaki token CSRF wysłać do twoich tras.
Typowo, powinieneś umieścić te rodzaje tras poza grupą oprogramowania pośredniczącego web
, którą App\Providers\RouteServiceProvider
stosuje do wszystkich tras w pliku routes/web.php
. Można jednak również wykluczyć te trasy, dodając ich identyfikatory URI do właściwości $except
oprogramowania pośredniczącego VerifyCsrfToken
:
<?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} Dla wygody, oprogramowanie pośredniczące CSRF jest automatycznie wyłączane dla wszystkich tras podczas uruchamiania testów.
X-CSRF-TOKEN
Oprócz sprawdzania tokena CSRF jako parametru POST, oprogramowanie pośredniczące App\Http\Middleware\VerifyCsrfToken
będzie również sprawdzać nagłówek żądania X-CSRF-TOKEN
. Można na przykład przechowywać token w znaczniku HTML meta
:
<meta name="csrf-token" content="{{ csrf_token() }}">
Następnie można poinstruować bibliotekę taką jak jQuery, aby automatycznie dodawała token do wszystkich nagłówków żądania. Zapewnia to prostą, wygodną ochronę CSRF dla twoich aplikacji opartych na AJAX-ie używających starszej technologii JavaScript:
$.ajaxSetup({ headers: { 'X-CSRF-TOKEN': $('meta').attr('content') }});
X-XSRF-TOKEN
Laravel przechowuje aktualny token CSRF w zaszyfrowanym XSRF-TOKEN
pliku cookie, który jest dołączany do każdej odpowiedzi generowanej przez framework. Możesz użyć wartości pliku cookie do ustawienia nagłówka żądania X-XSRF-TOKEN
.
Ten plik cookie jest głównie wysyłany jako udogodnienie dla programistów, ponieważ niektóre frameworki JavaScript i biblioteki, takie jak Angular i Axios, automatycznie umieszczają jego wartość w nagłówku X-XSRF-TOKEN
na żądaniach o tym samym pochodzeniu.