CSRF-bescherming: formulieren beveiligen tegen misbruik

Leer wat CSRF-aanvallen zijn, hoe CSRF-tokens formulieren beschermen en hoe je het inricht. Zo voorkom je dat je formulieren worden misbruikt.

Stel je voor dat iemand een bezoeker verleidt tot een klik op een link terwijl die is ingelogd bij zijn bank. Die link leidt naar een verborgen formulier dat, zonder dat de bezoeker het weet, bij de bank een verzoek indient om geld over te maken. De bank ziet een legitiem verzoek van een ingelogde gebruiker en voert het uit. De aanvaller heeft nu geld verplaatst met het account van het slachtoffer, zonder ooit het wachtwoord te kennen.

Dit is CSRF (Cross-Site Request Forgery): een aanval waarbij een aanvaller een slachtoffer ongemerkt een formulier of verzoek laat versturen naar een andere website waar het slachtoffer al is ingelogd.

Dit leer je: wat CSRF-aanvallen zijn en hoe ze werken, waarom ze zo gevaarlijk zijn, ook als andere beveiliging aanwezig is, hoe CSRF-tokens ze voorkomen en hoe je bescherming op je formulieren inricht.

Wat is CSRF?

CSRF (uitgesproken als "sea-surf") staat voor Cross-Site Request Forgery. Het is een aanval die misbruik maakt van het feit dat je browser, als je bent ingelogd op een website, je sessie automatisch vertrouwt en meestuurt bij elk verzoek aan die site, ook als het verzoek van een andere website komt.

De aanval werkt door een ingelogde bezoeker ongemerkt een formulier te laten versturen naar een website waar hij een account heeft. De aanvaller ziet het wachtwoord van het slachtoffer niet. Dat hoeft ook niet. Het slachtoffer moet alleen al ingelogd zijn, en dan wordt hij verleid tot een verzoek (zoals het versturen van een verborgen formulier) dat doet wat de aanvaller wil.

CSRF verschilt van andere aanvallen, omdat er geen inloggegevens gestolen of versleuteling gekraakt hoeven te worden. Het misbruikt het vertrouwen van het slachtoffer in de website. Het slachtoffer is al geauthenticeerd, dus de website vertrouwt verzoeken die van hem lijken te komen.

Zo werken CSRF-aanvallen

Een CSRF-aanval verloopt in drie stappen.

Stap 1: Het slachtoffer is ingelogd op je site

Iemand bezoekt je website en logt in op zijn account. Zijn browser heeft nu een actieve sessiecookie die bewijst dat hij is geauthenticeerd. Die sessie blijft actief zolang hij de site blijft gebruiken.

Stap 2: De aanvaller lokt hem naar een schadelijke pagina

Terwijl het slachtoffer nog is ingelogd op je site, bezoekt hij een pagina die de aanvaller beheert (bijvoorbeeld via een link op social media, een misleidende advertentie of een website die betrouwbaar lijkt). Op die pagina staat verborgen code die een formulier terugstuurt naar jouw site.

Stap 3: Het formulier wordt automatisch verstuurd met de sessie van het slachtoffer

Het verborgen formulier wordt naar je website gestuurd. Omdat het slachtoffer al is ingelogd, stuurt zijn browser de sessiecookie automatisch mee. Vanuit het perspectief van je formulier is dit een legitiem verzoek van een geauthenticeerde gebruiker. Het formulier verwerkt het alsof het slachtoffer het bewust heeft verstuurd.

De aanvaller heeft nu iets gedaan op je site met het account van het slachtoffer, zonder dat die het weet. Hij kan het wachtwoord hebben gewijzigd, geld hebben overgemaakt, het profiel hebben aangepast of gegevens hebben verstuurd.

Waarom dit werkt, ook als andere beveiliging aanwezig is

CSRF-aanvallen omzeilen verschillende gangbare beveiligingsmaatregelen:

HTTPS stopt CSRF niet. De gegevens zijn tijdens het transport versleuteld, maar de aanvaller hoeft ze niet te onderscheppen. Hij stuurt het verzoek gewoon vanuit de browser van het slachtoffer, en die browser vertrouwt het al.

Wachtwoordbeveiliging stopt CSRF niet. De aanvaller heeft het wachtwoord van het slachtoffer nooit nodig. Hij maakt alleen gebruik van het feit dat het slachtoffer al is ingelogd.

Een sterk inlogsysteem stopt CSRF niet. Zelfs als de authenticatie perfect is, werkt de aanval zodra het slachtoffer is ingelogd.

Daarom is CSRF-bescherming een eigen laag. Andere beveiligingsmaatregelen voorkomen het niet. Je moet formulieren er specifiek op ontwerpen dat ze CSRF-aanvallen weerstaan.

CSRF-tokens: zo stoppen ze de aanval

De oplossing is een CSRF-token. Dat is een unieke, onvoorspelbare reeks tekens die je server voor elk formulier maakt. Zo werkt het:

Je server maakt voor elke bezoeker een uniek token

Als iemand een pagina met een formulier laadt, genereert je server een willekeurig token en koppelt dat aan de sessie van die gebruiker. Dit token is elke keer anders en uniek voor die gebruiker.

Het token zit verwerkt in het formulier

Het token staat als verborgen veld in het HTML-formulier. Als de bezoeker het formulier verstuurt, gaat het token mee.

Je server controleert het token voordat de inzending wordt verwerkt

Als het formulier wordt verstuurd, controleert je server of het token in de inzending overeenkomt met het token dat je voor de sessie van deze gebruiker hebt gemaakt. Zo ja, dan wordt het formulier verwerkt. Zo nee (of als er geen token is), dan wordt het formulier geweigerd.

Het verborgen formulier van de aanvaller kan geen geldig token bevatten, omdat tokens onvoorspelbaar zijn en uniek per sessie. Een aanvaller op een ander domein kan het token niet zien of raden. Zijn aanval mislukt dus. Het verborgen formulier wordt verstuurd, maar je server weigert het omdat het token niet klopt.

Hoe een CSRF-token er in de praktijk uitziet

In HTML ziet een formulier met CSRF-bescherming er zo uit:

<form method="POST" action="/submit-form"> <input type="hidden" name="csrf_token" value="a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6"> <input type="email" name="email" placeholder="Your email"> <button type="submit">Submit</button> </form>

Het veld `csrf_token` is verborgen. De bezoeker ziet het niet, maar het wordt samen met zijn formuliergegevens verstuurd. Je server controleert het voordat het e-mailadres of andere gegevens worden verwerkt.

CSRF-bescherming voor verschillende soorten formulieren

Gewone HTML-formulieren

Standaard HTML-formulieren (die gegevens via POST naar je server sturen) hebben CSRF-tokens nodig. Dat geldt voor contactformulieren, inlogformulieren, formulieren om een wachtwoord te herstellen en elk formulier dat gegevens op je server wijzigt.

AJAX- en JavaScript-formulieren

Formulieren die via JavaScript naar een API-endpoint worden verstuurd, hebben ook CSRF-bescherming nodig. Het token kan in het formulier zelf zitten, in een cookie staan of uit een metatag worden gehaald voordat het verzoek wordt verstuurd.

Stateless API-verzoeken

Gebruikt je API authenticatie met tokens (zoals JWT), dan werkt CSRF-bescherming anders. De browser kan een JWT-token niet automatisch meesturen zoals een sessiecookie, dus traditionele CSRF is een kleinere bedreiging. Toch is het verstandig om voor extra bescherming ook een CSRF-token toe te voegen.

Andere beveiligingen die samenwerken met CSRF-tokens

CSRF-tokens zijn de belangrijkste verdediging, maar ze werken het best naast andere beveiligingsmaatregelen.

SameSite-cookies

Als je een sessiecookie instelt, kun je een `SameSite`-attribuut toevoegen dat de browser vertelt het cookie niet mee te sturen bij verzoeken vanaf een ander domein. Zo kan het verborgen formulier van de aanvaller de sessie van het slachtoffer helemaal niet gebruiken.

Controle van de Referer-header

Je server kan de Referer-header controleren om te zien waar het verzoek vandaan komt. Zegt een inzending van je domein te komen, maar toont de Referer een ander domein, dan is het waarschijnlijk een aanval. (Referer-headers kunnen echter worden vervalst, dus dit is geen volledige verdediging.)

Double-submit-cookiepatroon

Bij deze aanpak staat het CSRF-token zowel in een cookie als in een formulierveld. Je server controleert of ze overeenkomen voordat hij verwerkt. Dit komt minder vaak voor dan gewone tokens, maar werkt goed voor stateless applicaties.

Zo voer je CSRF-bescherming in

De details hangen af van je technische opzet, maar het patroon is hetzelfde:

  1. Genereer een uniek token per sessie. Als een gebruiker een sessie start of een pagina met een formulier laadt, maakt je backend een nieuw token.
  2. Bewaar het token op de server. Sla het op, gekoppeld aan de sessie van die gebruiker.
  3. Neem het token op in het formulier. Voeg het toe als verborgen veld in de HTML of als metatag die JavaScript kan lezen.
  4. Controleer bij het versturen. Controleer voordat je formuliergegevens verwerkt of het verstuurde token overeenkomt met het bewaarde token van die sessie.
  5. Genereer opnieuw na gevoelige acties. Maak een nieuw token nadat een gebruiker zijn wachtwoord wijzigt of iets belangrijks doet.

De meeste moderne frameworks (Django, Rails, Laravel, ASP.NET) regelen het genereren en controleren van CSRF-tokens automatisch. Gebruik je een framework, dan staat CSRF-bescherming meestal standaard aan. Zorg er alleen voor dat je het niet per ongeluk uitschakelt.

Veelgemaakte fouten die formulieren kwetsbaar maken

CSRF-bescherming uitschakelen voor het gemak. Sommige ontwikkelaars zetten CSRF-controles uit om API-tests makkelijker te maken of hun code te vereenvoudigen. Doe dit niet. Het levert een echte kwetsbaarheid op.

Een vast token voor alle gebruikers gebruiken. Het token moet uniek zijn voor de sessie van elke gebruiker. Een token dat voor iedereen gelijk is (of voor alle gebruikers op alle dagen), beschermt niet tegen CSRF.

Tokens niet vernieuwen. Gebruik je wekenlang hetzelfde token, dan heeft een aanvaller meer tijd om het te misbruiken. Vernieuw tokens regelmatig en altijd na gevoelige handelingen.

Alleen op SameSite-cookies vertrouwen. SameSite helpt, maar is niet genoeg. Gebruik CSRF-tokens als belangrijkste verdediging en SameSite als back-up.

Tokens op sommige formulieren vergeten. Beveilig je sommige formulieren met tokens en andere niet, dan gebruiken aanvallers de onbeveiligde formulieren. Elk formulier dat gegevens wijzigt, heeft bescherming nodig.

Wat WEMASY doet voor CSRF-bescherming

Formulieren van WEMASY hebben automatisch CSRF-tokenbescherming op elk formulier dat je maakt. Je hoeft het niet in te stellen en er niet over na te denken. Verstuurt een bezoeker een formulier, dan controleert WEMASY het token voordat de inzending wordt opgeslagen. Deze bescherming is ingebouwd en staat standaard aan.

Lees meer over de opties voor formulierbeveiliging op de prijspagina.

Veelgestelde vragen

Kan een aanvaller een CSRF-token raden?
In theorie niet. CSRF-tokens zijn cryptografisch willekeurig en veranderen vaak. Een aanvaller die een token probeert te raden, zou miljarden mogelijkheden moeten proberen. In de praktijk zijn CSRF-tokens zo onvoorspelbaar dat raden geen haalbare aanval is. De kracht van het token zit in willekeur en uniekheid, niet in het geheimhouden ervan.
Wat gebeurt er als een bezoeker een formulier verstuurt en het token ongeldig is?
De inzending wordt geweigerd. Je server verwerkt de formuliergegevens niet en slaat de inzending niet op. De bezoeker ziet meestal een foutmelding (zoals "Sessie verlopen" of "Ongeldig verzoek") en wordt gevraagd het opnieuw te proberen. Voor de aanvaller werkt het verborgen formulier simpelweg niet.
Heb ik CSRF-bescherming nodig als mijn formulier geen login vereist?
Ja. CSRF-aanvallen kunnen ook werken op formulieren zonder authenticatie. Een aanvaller kan CSRF gebruiken om een bezoeker ongewenste gegevens te laten versturen naar elk formulier, of de bezoeker nu is ingelogd of niet. Elk formulier dat inzendingen verwerkt, heeft CSRF-bescherming nodig.
Wat is het verschil tussen CSRF en XSS?
Bij Cross-Site Scripting (XSS) plaatst een aanvaller schadelijke code in je website die in de browsers van bezoekers draait. Bij CSRF laat een aanvaller de browser van een bezoeker een formulier naar een andere site versturen. Het zijn verschillende aanvallen met verschillende verdedigingen. CSRF-tokens beschermen tegen CSRF; invoervalidatie en opschoning van invoer beschermen tegen XSS.
En aanvallen op mobiele apps? Werken CSRF-tokens daar?
Mobiele apps zijn minder kwetsbaar voor traditionele CSRF-aanvallen, omdat ze niet automatisch cookies meesturen zoals browsers. Toch horen mobiele apps authenticatie met tokens of certificaten te gebruiken. Gebruikt een mobiele app cookies of tokens die automatisch met verzoeken worden meegestuurd, dan moet hij ook CSRF-tokens controleren als extra beschermlaag.

Zet het meteen
in je eigen website.

Start gratis met WEMASY en bouw je site in een paar minuten.