- Esittely
- CSRF-pyyntöjen estäminen
- URI:iden poissulkeminen
- X-CSRF-Token
- X-XSRF-Token
Esittely
Cross-site request forgeries on eräänlainen pahantahtoinen hyväksikäyttö, jossa luvattomia komentoja suoritetaan todennetun käyttäjän puolesta. Onneksi Laravel helpottaa sovelluksesi suojaamista CSRF-hyökkäyksiltä (cross-site request forgery).
Haavoittuvuuden selitys
Siltä varalta, että cross-site request forgeries ei ole sinulle tuttu, käydään läpi esimerkki siitä, miten tätä haavoittuvuutta voidaan hyödyntää. Kuvittele, että sovelluksessasi on /user/email
-reitti, joka hyväksyy POST
-pyynnön autentikoidun käyttäjän sähköpostiosoitteen muuttamiseksi. Todennäköisesti tämä reitti odottaa email
-syöttökentän sisältävän sähköpostiosoitteen, jota käyttäjä haluaa alkaa käyttää.
Ilman CSRF-suojausta haitallinen verkkosivusto voisi luoda HTML-lomakkeen, joka osoittaa sovelluksesi /user/email
-reittiin ja lähettää haitallisen käyttäjän oman sähköpostiosoitteen:
<form action="https://your-application.com/user/email" method="POST"> <input type="email" value=""></form><script> document.forms.submit();</script>
Jos haitallinen verkkosivusto lähettää lomakkeen automaattisesti, kun sivu ladataan, haitallisen käyttäjän tarvitsee vain houkutella sovelluksesi pahaa-aavistamaton käyttäjä vierailemaan sivustollaan, ja hänen sähköpostiosoitteensa muuttuu sovelluksessasi.
Tämän haavoittuvuuden estämiseksi meidän on tarkastettava jokainen saapuva POST
-, PUT
-, PATCH
– tai DELETE
-pyyntö salaisen istuntoarvon varalta, johon haitallinen sovellus ei pääse käsiksi.
CSRF-pyyntöjen estäminen
Laravel luo automaattisesti CSRF-”tokenin” kullekin sovelluksen hallinnassa olevalle aktiiviselle käyttäjäistunnolle. Tätä tokenia käytetään todentamaan, että todennettu käyttäjä on se henkilö, joka todella tekee pyyntöjä sovellukselle. Koska tämä token tallennetaan käyttäjän istuntoon ja se muuttuu joka kerta, kun istunto luodaan uudelleen, pahantahtoinen sovellus ei pääse siihen käsiksi.
Nykyisen istunnon CSRF-tunnisteeseen pääsee käsiksi pyynnön istunnon kautta tai csrf_token
-aputoiminnon avulla:
use Illuminate\Http\Request;Route::get('/token', function (Request $request) { $token = $request->session()->token(); $token = csrf_token(); // ...});
Kun tahansa määrittelet sovelluksessasi HTML-lomakkeen, sinun tulee sisällyttää piilotettu CSRF-_token
-kenttä lomakkeeseen, jotta CSRF-suojauksen välitysohjelmisto voi validoida pyynnön. Yksinkertaisuuden vuoksi voit käyttää @csrf
Blade-direktiiviä piilotetun token-syöttökentän luomiseen:
<form method="POST" action="/profile"> @csrf <!-- Equivalent to... --> <input type="hidden" name="_token" value="{{ csrf_token() }}" /></form>
App\Http\Middleware\VerifyCsrfToken
-väliohjelmisto, joka sisältyy oletusarvoisesti web
-väliohjelmistoryhmään, tarkistaa automaattisesti, että pyynnön syötteessä oleva token vastaa istuntoon tallennettua tokenia. Kun nämä kaksi tokenia täsmäävät, tiedämme, että pyynnön alullepanija on todennettu käyttäjä.
CSRF-tunnisteet & SPA:t
Jos rakennat SPA:ta, joka käyttää Laravelia API-taustapalveluna, sinun kannattaa tutustua Laravel Sanctum -dokumentaatioon saadaksesi tietoa API:n todennuksesta ja suojautumisesta CSRF-haavoittuvuuksia vastaan.
URI:iden sulkeminen CSRF-suojauksen ulkopuolelle
Joskus saatat haluta sulkea joukon URI:itä CSRF-suojauksen ulkopuolelle. Jos esimerkiksi käytät Stripeä maksujen käsittelyyn ja hyödynnät heidän webhook-järjestelmäänsä, sinun on jätettävä Stripen webhook-käsittelijän reitti CSRF-suojauksen ulkopuolelle, koska Stripe ei tiedä, mikä CSRF-token lähetetään reiteillesi.
Tyypillisesti sinun pitäisi sijoittaa tämäntyyppiset reitit web
-väliohjelmistoryhmän ulkopuolelle, jota App\Providers\RouteServiceProvider
sovelletaan kaikkiin reitteihin routes/web.php
-tiedostossa. Voit kuitenkin sulkea reitit pois myös lisäämällä niiden URI:t VerifyCsrfToken
-väliohjelmiston $except
-ominaisuuteen:
<?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} Mukavuuden vuoksi CSRF-väliohjelmisto poistetaan automaattisesti käytöstä kaikkien reittien osalta testejä suoritettaessa.
X-CSRF-TOKEN
Sen lisäksi, että App\Http\Middleware\VerifyCsrfToken
-väliohjelmisto tarkistaa CSRF-tokenin POST-parametrina, se tarkistaa myös X-CSRF-TOKEN
-pyyntöotsikon. Voit esimerkiksi tallentaa tunnisteen HTML meta
-tagiin:
<meta name="csrf-token" content="{{ csrf_token() }}">
Tällöin voit ohjeistaa jQueryn kaltaista kirjastoa lisäämään tunnisteen automaattisesti kaikkiin pyyntöotsakkeisiin. Tämä tarjoaa yksinkertaisen ja kätevän CSRF-suojauksen AJAX-pohjaisille sovelluksillesi, jotka käyttävät vanhaa JavaScript-tekniikkaa:
$.ajaxSetup({ headers: { 'X-CSRF-TOKEN': $('meta').attr('content') }});
X-XSRF-TOKEN
Laravel tallentaa nykyisen CSRF-tunnisteen salattuun XSRF-TOKEN
evästeeseen, joka sisältyy jokaiseen kehyksen tuottamaan vastaukseen. Voit käyttää evästeen arvoa asettaaksesi X-XSRF-TOKEN
-pyyntöotsikon.
Tämä eväste lähetetään ensisijaisesti kehittäjien mukavuussyistä, koska jotkin JavaScript-kehykset ja -kirjastot, kuten Angular ja Axios, sijoittavat sen arvon automaattisesti X-XSRF-TOKEN
-otsikkoon samasta alkuperästä tulevissa pyynnöissä.