CSRF grondig begrijpen
Biedt een diepgaande verkenning van Cross-Site Request Forgery (CSRF)-aanvallen, waarin hun mechanica wordt uitgelegd, voorbeelden worden getoond en verschillende preventiemethoden worden beschreven om de beveiliging van webapplicaties te verbeteren.
Bij het werken aan webontwikkeling, vooral met cookies, horen we vaak zinnen zoals "deze instelling helpt CSRF te voorkomen". Veel mensen hebben echter alleen een vaag idee van wat "CSRF" echt betekent.
Vandaag duiken we diep in CSRF (Cross-Site Request Forgery), een veelvoorkomende beveiligingsfout op het web. Dit zal ons helpen om CSRF-gerelateerde problemen effectiever aan te pakken.
Wat is CSRF?
CSRF (Cross-Site Request Forgery) is een type webaanval waarbij aanvallers geauthenticeerde gebruikers misleiden om onbedoelde acties uit te voeren. In eenvoudige termen is het "hackers die zich voordoen als gebruikers om ongeoorloofde acties uit te voeren".
Hoe werkt CSRF
Om CSRF te begrijpen, moeten we enkele belangrijke concepten begrijpen:
Zelfde-oorsprongbeleid van de browser
Het zelfde-oorsprongbeleid is een beveiligingsfunctie in browsers die beperkt hoe een document of script van de ene oorsprong kan interageren met bronnen van een andere oorsprong.
Een oorsprong bestaat uit een protocol (zoals HTTP of HTTPS), domeinnaam en poortnummer. Bijvoorbeeld, https://example.com:443
is één oorsprong, terwijl https://demo.com:80
een andere is.
Het zelfde-oorsprongbeleid beperkt de toegang tot gegevens tussen pagina's van verschillende oorsprongen, wat betekent:
- JavaScript van de ene oorsprong kan de DOM van een andere oorsprong niet lezen
- JavaScript van de ene oorsprong kan de Cookie, IndexedDB of lokaal opgeslagen gegevens van een andere oorsprong niet lezen
- JavaScript van de ene oorsprong kan geen AJAX-verzoeken naar een andere oorsprong sturen (tenzij CORS wordt gebruikt)
Echter, om de openheid en interoperabiliteit van het web te behouden (zoals het laden van bronnen van CDNs of het verzenden van verzoeken naar derde-partij API's voor logging), beperkt het zelfde-oorsprongbeleid geen cross-origin netwerkverzoeken:
- Pagina's kunnen GET- of POST-verzoeken naar elke oorsprong sturen (zoals het laden van afbeeldingen of het indienen van formulieren)
- Bronnen van elke oorsprong kunnen worden opgenomen (zoals
<script>
,<img>
,<link>
,<iframe>
tags)
Automatisch cookies verzenden mechanisme
Het automatische cookies verzenden mechanisme is een belangrijke functie van browsers. Wanneer een browser een verzoek naar een domein verzendt, voegt het automatisch alle cookies voor dat domein toe. Dit proces is automatisch en vereist geen JavaScript-code of gebruikersinteractie.
Dit mechanisme stelt websites in staat om eenvoudig de inlogstatus van gebruikers te onthouden omdat elk verzoek automatisch de identiteit van de gebruiker meedraagt.
Vetgedrukt
Bijvoorbeeld, wanneer je inlogt op een bankwebsite (bank.com
) en een identiteitscookie krijgt, dan, wanneer je klikt om je uitschrijving te bekijken, vindt de browser automatisch alle cookies die overeenkomen met bank.com
en voegt ze toe aan het uitschrijvingsverzoek. De server van de bank kan je dan vanaf de achterkant identificeren en je uitschrijvingsinformatie retourneren.
CSRF-aanval stappen
-
De gebruiker logt in op de doelwebsite (zoals een banksite) en krijgt een authenticatiecookie. Deze stap maakt gebruik van het automatische cookies verzenden mechanisme. Nadat de banksite een identiteitsauthenticatiecookie heeft ingesteld, voegt de browser automatisch deze cookie toe aan elk verzoek dat naar die site wordt gestuurd.
-
Zonder uit te loggen bezoekt de gebruiker een kwaadaardige website. Op dit punt, vanwege het zelfde-oorsprongbeleid, kan de kwaadaardige site de cookie van de banksite niet direct lezen of wijzigen. Dit beschermt de identiteitsinformatie van de gebruiker tegen directe diefstal.
-
De kwaadaardige site bevat een verzoek aan de doelsite (zoals een overboekingshandeling). Hoewel het zelfde-oorsprongbeleid cross-origin toegang beperkt, staat het cross-origin netwerkverzoeken toe, zoals verzoeken die worden geïnitieerd via
<img>
,<form>
tags. Aanvallers maken misbruik van dit "lek". -
De browser van de gebruiker verzendt automatisch dit verzoek, samen met de cookie van de doelsite. Dit is de kern van de CSRF-aanval. Het maakt gebruik van zowel het zelfde-oorsprongbeleid dat cross-origin verzoeken toestaat als het automatische cookies verzenden mechanisme (zelfs door kwaadaardige sites geïnitieerde verzoeken zullen cookies dragen die overeenkomen met het domein).
-
De doelsite ontvangt het verzoek, verifieert dat de cookie geldig is en voert de handeling uit. De server kan niet zien of dit verzoek afkomstig is van een legitieme gebruikersactie omdat de bijgevoegde cookie geldig is.
Voorbeeld van een CSRF-aanval
Laten we illustreren hoe een CSRF-aanval gebeurt met een specifiek voorbeeld. We zullen een fictieve bankwebsite bank.com
als voorbeeld gebruiken.
Eerst bezoekt de gebruiker https://bank.com
en logt in op zijn account.
Na succesvolle inlog stelt de server een authenticatiecookie in, bijvoorbeeld:
De gebruiker voert een overboekingshandeling uit op de bankwebsite, bijvoorbeeld het overboeken van $1000 naar Alice. Deze handeling kan een verzoek zoals dit verzenden:
Stel nu dat een aanvaller een kwaadaardige website https://evil.com
creëert met de volgende HTML:
Wanneer de gebruiker op de https://evil.com
link klikt zonder uit te loggen van zijn bankrekening, omdat hij al ingelogd is op bank.com
, heeft de browser een geldige session_id
cookie.
Nadat de kwaadaardige pagina is geladen, dient deze automatisch het verborgen formulier in, waardoor een overboekingsverzoek naar https://bank.com/transfer
wordt verzonden.
De browser van de gebruiker voegt de bank.com
cookie automatisch toe aan dit verzoek. De server van bank.com
ontvangt het verzoek, verifieert dat de cookie geldig is, en voert vervolgens deze ongeoorloofde overboekingshandeling uit.
Veelgebruikte methoden om CSRF-aanvallen te voorkomen
Hier zijn verschillende veelgebruikte CSRF-verdedigingsmethoden. We leggen gedetailleerd het principe van elke methode uit en hoe deze effectief CSRF-aanvallen voorkomt:
Gebruik van CSRF-tokens
CSRF-tokens zijn een van de meest voorkomende en effectieve methoden om CSRF-aanvallen te verdedigen. Hier is hoe het werkt:
- De server genereert een unieke, onvoorspelbare token voor elke sessie.
- Deze token wordt ingebed in alle formulieren voor gevoelige handelingen.
- Wanneer de gebruiker een formulier indient, verifieert de server de geldigheid van de token.
Omdat de CSRF-token een unieke waarde is die aan de sessie van de gebruiker is gebonden, en de aanvaller deze waarde niet kan kennen of raden (aangezien het anders is voor elke sessie), zelfs als de aanvaller de gebruiker misleidt in het verzenden van een verzoek, wordt het verzoek door de server afgewezen vanwege het ontbreken van een geldige CSRF-token.
Implementatievoorbeeld:
Aan de serverzijde (met Node.js en Express):
In frontend JavaScript:
Controle van Referer
-header
De Referer
-header bevat de URL van de pagina die het verzoek heeft geïnitieerd. Door de Referer
-header te controleren, kan de server bepalen of het verzoek van een legitieme bron komt.
Omdat CSRF-aanvallen meestal van verschillende domeinen komen, zal de 'Referer'-header de domeinnaam van de aanvaller weergeven. Door te controleren of de Referer
de verwachte waarde is, kunnen verzoeken van onbekende bronnen worden geblokkeerd.
Het is echter vermeldenswaard dat deze methode niet volledig betrouwbaar is, aangezien sommige browsers de Referer-header mogelijk niet verzenden, en gebruikers de Referer-header kunnen uitschakelen via browserinstellingen of plugins.
Implementatievoorbeeld:
Gebruik van de SameSite
-cookie-attribuut
SameSite
is een cookie-attribuut dat wordt gebruikt om te regelen of cookies worden verzonden met cross-site verzoeken. Het heeft drie mogelijke waarden:
Strict
: Cookies worden alleen verzonden in zelfde-site verzoeken.Lax
: Cookies worden verzonden in zelfde-site verzoeken en top-level navigatie.None
: Cookies worden verzonden in alle cross-site verzoeken (moet worden gebruikt met hetSecure
attribuut).
Wanneer SameSite
is ingesteld op Strict
, kan het volledig voorkomen dat websites van derden cookies verzenden, wat effectief CSRF-aanvallen voorkomt.
Als SameSite
is ingesteld op Lax
, beschermt het gevoelige handelingen terwijl het enkele veelvoorkomende cross-site gebruikssituaties toestaat (zoals een website vanuit externe links betreden).
Implementatievoorbeeld:
Gebruik van aangepaste verzoekheaders
Voor AJAX-verzoeken kunnen aangepaste verzoekheaders worden toegevoegd. Vanwege de beperkingen van het zelfde-oorsprongbeleid kunnen aanvallers geen aangepaste headers instellen in cross-origin verzoeken. De server kan controleren op de aanwezigheid van deze aangepaste header om de legitimiteit van het verzoek te verifiëren.
Implementatievoorbeeld:
Aan de voorkant:
Aan de serverzijde:
Dubbele cookie verificatie
Dubbele cookie verificatie is een effectieve CSRF-verdedigingstechniek. Het kernprincipe is dat de server een willekeurige token genereert, deze instelt als zowel een cookie als deze in de pagina inbedt (meestal als een verborgen formulierveld). Wanneer de browser een verzoek verzendt, voegt deze automatisch de cookie toe, terwijl de JavaScript van de pagina de token verzendt als een verzoekparameter. Vervolgens verifieert de server of de token in de cookie overeenkomt met de token in de verzoekparameters.
Hoewel aanvallers de cookie van de doelwebsite kunnen opnemen in cross-site verzoeken, kunnen ze de waarde van de cookie niet lezen of wijzigen, noch kunnen ze toegang krijgen tot of de tokenwaarde in de pagina wijzigen. Door te vereisen dat het verzoek tokens bevat uit zowel de cookie als de parameters, wordt ervoor gezorgd dat het verzoek afkomstig is van een bron met toestemming om de cookie te lezen, waardoor effectief wordt verdedigd tegen CSRF-aanvallen.
Gebruik van herauthenticatie voor gevoelige handelingen
Voor bijzonder gevoelige handelingen (zoals het wijzigen van wachtwoorden of het uitvoeren van grote overboekingen) kan van gebruikers worden verlangd dat ze zich opnieuw authentiseren. Dit biedt gebruikers een extra beveiligingscontrolepunt. Zelfs als een gebruiker met succes een CSRF-aanval uitvoert, kunnen ze de stap voor herauthenticatie niet passeren.
Implementatievoorstellen:
- Voordat gevoelige handelingen worden uitgevoerd, naar een aparte authenticatiepagina omleiden.
- Op deze pagina van de gebruiker vragen om zijn wachtwoord of andere identiteitsverificatie-informatie in te voeren.
- Na het succesvol passes van de verificatie een eenmalige token genereren en deze token in latere gevoelige handelingen gebruiken.
Samenvatting
Door deze diepgaande discussie hopen we dat je nu een meer uitgebreide begrip hebt van CSRF-aanvallen. We hebben niet alleen geleerd hoe CSRF werkt, maar ook verschillende effectieve verdedigingsmaatregelen verkend. Al deze methoden kunnen de veiligheid van webapplicaties effectief verbeteren.
We hopen dat deze kennis je zal helpen CSRF-gerelateerde problemen beter aan te pakken in je dagelijkse ontwikkeling en veiliger webapplicaties te bouwen.