SameSite-attribuut op Lax in plaats van Strict
CWE-1275CWE-352OWASP A07:2021Bijgewerkt 3 september 20264 min leestijd
SameSite=Lax stuurt het sessiecookie nog steeds mee wanneer een gebruiker via een externe link naar uw site navigeert. Dat blokkeert de meeste CSRF-aanvallen, maar niet die welke via een gewone navigatie verlopen, en het helpt niet bij endpoints die state wijzigen op een GET-verzoek. Voor gevoelige applicaties is Strict de veiliger keuze.
Sinds browsers SameSite=Lax als standaard hanteren, is een groot deel van de klassieke CSRF-aanvallen vanzelf verdwenen. Dat succes maakt het verleidelijk om de instelling als afgehandeld te beschouwen. Er blijft echter een specifieke categorie over die Lax bewust doorlaat. In dit artikel leest u welke dat is en wanneer de stap naar Strict de moeite waard is.
Wat doet het SameSite-attribuut?
Het SameSite-attribuut bepaalt of de browser een cookie meestuurt bij een verzoek dat vanaf een andere site vertrekt. Er zijn drie waarden. Strict stuurt de cookie uitsluitend mee bij verzoeken die binnen uw eigen site ontstaan. Lax doet hetzelfde, met één uitzondering: bij een navigatie op het hoogste niveau met een veilige methode (kortweg, wanneer de gebruiker op een link klikt en daarmee naar uw site gaat) gaat de cookie wél mee. None schakelt de beperking helemaal uit.
Die ene uitzondering bij Lax is er om een praktische reden. Zonder die uitzondering zou iedereen die via een e-mail, een zoekresultaat of een gedeelde link op uw site komt, worden begroet met een inlogscherm terwijl hij gewoon een geldige sessie heeft. Dat is hinderlijk genoeg om Lax tot het gangbare compromis te maken.
Het is dus geen fout maar een afweging. Vergelijk het met een deur die op slot zit, behalve voor wie netjes aanbelt en wordt binnengelaten. Voor de meeste gebouwen is dat prima. Voor een kluisruimte niet.
Waar laat Lax nog iets door?
Het verschil wordt concreet bij endpoints die iets wijzigen en bereikbaar zijn via een navigatie.
Kwetsbaar:
Set-Cookie: sid=8f42c19ade7b3f5c; HttpOnly; Secure; SameSite=Lax; Path=/
Deze cookie is redelijk beschermd, en een klassieke CSRF-aanval met een automatisch verzonden POST-formulier vanaf een vreemde site werkt niet meer: bij een cross-site POST blijft de cookie thuis. Alleen bestaat er ergens in de applicatie een handeling die via een GET verloopt, dan verandert het beeld:
<!-- Op de pagina van de aanvaller; één klik van het slachtoffer volstaat -->
<a href="https://portaal.example/abonnement/opzeggen?bevestig=ja">
Bekijk uw factuur
</a>
Dit is een navigatie op het hoogste niveau met een veilige methode, en dus stuurt de browser de sessiecookie gewoon mee. De handeling wordt uitgevoerd namens de ingelogde gebruiker. Hetzelfde geldt voor een aanvaller die met JavaScript een navigatie afdwingt via window.open of een <form method="GET">. Ook de eerste minuten na het zetten van een cookie kennen browsers een uitzondering waarbij Lax zich soepeler gedraagt, wat een klein maar reëel tijdvenster oplevert.
Veilig:
Set-Cookie: __Host-sid=8f42c19ade7b3f5c; HttpOnly; Secure; SameSite=Strict; Path=/
Met Strict gaat de cookie bij geen enkel extern gestart verzoek mee, ook niet bij het volgen van een link. De aanval hierboven levert dan een uitgelogde sessie op in plaats van een opgezegd abonnement.
Wilt u Strict gebruiken zonder gebruikers vanaf externe links op het inlogscherm te laten stranden, dan is het gebruikelijke patroon twee cookies: een kortlevende Lax-cookie die uitsluitend dient om te herkennen dat er een sessie bestaat, en de eigenlijke sessiecookie op Strict. De landingspagina ziet dan dat de gebruiker bekend is en stuurt hem via een interne navigatie door, waarna de Strict-cookie wél meegaat.
Wat is de impact van SameSite op Lax?
Op zichzelf is dit een hardeningbevinding met een lage ernst. Lax blokkeert de meeste aanvalspatronen, en veel applicaties hebben daarnaast CSRF-tokens waardoor het resterende risico klein blijft.
De betekenis ontstaat in combinatie met andere keuzes. Bestaan er endpoints die state wijzigen via een GET-verzoek (een opzegging, een bevestiging, een activatie of een verwijdering) dan is de bescherming voor precies die endpoints afwezig. Verder juist dat soort routes ontstaat vaak per ongeluk, bijvoorbeeld doordat een bevestigingslink in een e-mail nu eenmaal een GET is.
Een tweede factor is de aanwezigheid van subdomeinen. Omdat die als dezelfde site gelden, biedt SameSite in geen enkele variant bescherming tegen een aanval die vanaf een van uw eigen subdomeinen wordt uitgevoerd. Organisaties met veel subdomeinen, testomgevingen of door leveranciers beheerde pagina’s hebben aan dit attribuut dus minder dan het lijkt.
Hoe controleer je je SameSite-instelling?
De waarde van het attribuut is direct af te lezen uit de Set-Cookie-header. Interessanter is de vraag wat die waarde in deze specifieke applicatie betekent, en dat vraagt om een inventarisatie van de endpoints.
Een tester zoekt naar routes die iets wijzigen maar bereikbaar zijn via een GET: bevestigingslinks, activatie-URL’s, opzeggingen, en beheerfuncties die met een link zijn geïmplementeerd. Voor elk daarvan wordt gecontroleerd of er een CSRF-token wordt geëist. Verder wordt gekeken of het attribuut consistent op alle authenticatiecookies staat, of er cookies met SameSite=None zijn die dat niet nodig hebben, en of er subdomeinen bestaan die als opstappunt kunnen dienen. AssistSec beoordeelt dit niet als losse instelling maar als onderdeel van de CSRF-weerbaarheid als geheel, omdat de vraag niet is welke waarde er staat maar of een aanvaller in de praktijk nog een handeling kan afdwingen.
Hoe stel je SameSite veilig in?
- Gebruik
SameSite=Strictvoor sessiecookies van applicaties met gevoelige of onomkeerbare handelingen. - Werk met een tweecookiepatroon als u Strict wilt gebruiken zonder gebruikers vanaf externe links te hinderen.
- Blijf CSRF-tokens gebruiken op elke statewijzigende actie; SameSite is een aanvulling, geen vervanging.
- Voer nooit een wijziging uit op een
GET-verzoek, ook niet voor bevestigingslinks uit e-mails. - Zet
SameSite=Nonealleen op cookies die aantoonbaar in een cross-site context nodig zijn, altijd samen metSecure. - Beschouw subdomeinen als onderdeel van uw aanvalsoppervlak, omdat SameSite ze als dezelfde site behandelt.
- Controleer de
Origin- enReferer-header bij gevoelige acties als extra laag. - Leg de gekozen waarde vast in uw sessieconfiguratie, zodat nieuwe cookies hem automatisch overnemen.
Bronnen
Veelgestelde vragen
Wat is precies het verschil tussen Lax en Strict?
Bij Strict gaat de cookie nooit mee wanneer het verzoek vanaf een andere site vertrekt, ook niet bij het volgen van een gewone link. Bij Lax gaat hij wél mee bij navigatie op het hoogste niveau met een veilige methode, dus wanneer iemand op een link klikt. Dat verschil is precies waar het risico zit.
Waarom kiezen zoveel applicaties dan voor Lax?
Om praktische redenen. Met Strict komt een gebruiker die via een link in een e-mail of vanuit een zoekmachine binnenkomt op het inlogscherm terecht, ook al heeft hij een geldige sessie. Dat wordt als hinderlijk ervaren. Lax is een compromis tussen bruikbaarheid en veiligheid, geen maximale bescherming.
Is SameSite genoeg om CSRF te voorkomen?
Nee, en dat is de belangrijkste boodschap. SameSite is een sterke basislaag, maar dekt niet elk geval af: subdomeinen gelden als dezelfde site, oudere browsers passen het niet toe, en bij Lax blijven navigatiegebaseerde aanvallen mogelijk. Combineer het altijd met CSRF-tokens op statewijzigende acties.
Wat doet SameSite=None?
Die waarde schakelt de bescherming volledig uit en is alleen bedoeld voor cookies die bewust in een cross-site context nodig zijn, bijvoorbeeld bij een ingesloten widget. Browsers accepteren het alleen in combinatie met Secure. Gebruik het nooit voor een sessiecookie van een gewone applicatie.
Verwante artikelen
- KwetsbaarhedenCWE-942A05:2021Onveilige CORS-configuratieEen CORS-beleid dat elke herkomst weerspiegelt, geeft vreemde sites toegang tot uw API namens ingelogde gebruikers. Lees hoe u het goed instelt.
- KwetsbaarhedenCWE-352A01:2021Cross-site request forgery (CSRF)Cross-site request forgery (CSRF) uitgelegd: hoe een aanvaller de browser van een ingelogde gebruiker misbruikt voor ongewenste acties, en hoe u het voorkomt.
- KwetsbaarhedenCWE-613A07:2021Sessie blijft geldig na uitloggenUitloggen dat alleen de cookie wist, laat het token aan serverzijde intact. Lees hoe een buitgemaakte sessie dan gewoon bruikbaar blijft.
- KwetsbaarhedenCWE-1004A07:2021Onbeschermd authenticatiecookieEen sessiecookie zonder HttpOnly, Secure en SameSite is uitleesbaar, onderschepbaar en misbruikbaar. Lees wat elk attribuut precies afdekt.