Login, browser og API-sikkerhed
CSRF i webapps: stop skjulte handlinger fra andre websites
Når browseren automatisk sender en login-cookie, kan et fremmed website forsøge at få brugerens browser til at udføre en handling i jeres app. CSRF-beskyttelse gør det muligt for serveren at skelne mellem appens egne ændringer og en forfalsket request.
Udgivet 19. oktober 2026 · Ca. 11 minutters læsetid
Det korte svar
Find alle requests, der opretter, ændrer eller sletter noget. Hvis browseren automatisk sender brugerens session, skal de requests have en servervalideret CSRF-kontrol. Brug først den vedligeholdte funktion i appens framework. Supplér med en bevidst SameSite-cookie, snæver CORS, relevante Fetch Metadata-kontroller og ny bekræftelse ved særligt følsomme handlinger. Test derefter, at manglende og ugyldig kontrol faktisk bliver afvist.
Forstå hvornår appen er udsat
CSRF udnytter ikke nødvendigvis en stjålet adgangskode. Angriberen forsøger i stedet at få en allerede indlogget browser til at sende en request med brugerens cookies. Risikoen er derfor størst, når serveren accepterer en ændrende request alene på baggrund af credentials, som browseren vedhæfter automatisk.
- Cookie-session
- Browseren kan sende sessionen automatisk. Ændrende endpoints skal vurderes for CSRF.
- Bearer-token i header
- Et token, som klientkoden selv tilføjer, ændrer CSRF-billedet, men skal stadig beskyttes mod tyveri, XSS og forkert CORS.
- Klassiske formularer
- Et andet website kan sende visse formularrequests på tværs af origins. Brug frameworkets tokenbeskyttelse.
- JavaScript-API
- En krævet custom header eller token kan gøre requesten ikke-simpel, hvis server og CORS er sat stramt op.
Det afgørende er ikke, om brugerfladen kalder det en formular eller et API. Se på den faktiske request, hvordan credentials bliver sendt, og hvad serveren kræver, før den udfører handlingen.
Kortlæg alle handlinger der ændrer noget
Lav en liste over de endpoints, som kan ændre data, adgang eller drift. Tag også de mindre synlige med: upload, import, invitationer, profilændringer, supportværktøjer, integrationstilslutning og administrative genveje.
| Kontrolpunkt | Spørgsmål | Typisk fund |
|---|---|---|
| HTTP-metode | Kan GET, HEAD eller OPTIONS ændre data? | Et link eller billede kan udløse en handling |
| Credentials | Sendes sessionen automatisk som cookie? | Serveren ser en gyldig bruger, men ikke brugerens hensigt |
| Requesttype | Accepterer endpointet simple formular-content types? | Et fremmed website kan sende requesten uden preflight |
| Serverkontrol | Valideres token, header eller requestkontekst? | Frontend sender et token, som backend aldrig kontrollerer |
| Konsekvens | Hvad kan brugerens rettigheder gøre? | E-mail, rolle, betaling eller data ændres ubemærket |
RFC 9110 definerer GET, HEAD og OPTIONS som sikre metoder med læsende semantik. Lad dem ikke slette, godkende, sende eller ændre noget. En POST-, PUT-, PATCH- eller DELETE-request er dog ikke beskyttet blot på grund af sit metodenavn.
Brug frameworkets CSRF-funktion før hjemmelavet kode
Mange serverframeworks kan generere og validere CSRF-tokens. Brug den dokumenterede funktion til den konkrete version i stedet for at opfinde tokenformat, lagring og sammenligning selv. Beskyttelsen skal gælde på serveren for hver relevant request; et skjult felt eller en header i frontend er ikke nok alene.
- 1. Aktivér den vedligeholdte mekanisme: Følg frameworkets officielle dokumentation og behold middleware-rækkefølge og sikre standarder.
- 2. Send kontrollen med legitime requests: Brug skjult felt til beskyttede formularer eller den dokumenterede header til JavaScript-kald.
- 3. Valider før handlingen: Afvis requesten, før data ændres, jobs startes eller eksterne systemer kaldes.
- 4. Hold token ude af URL og logs: Query strings kan ende i browserhistorik, referrerdata, netværksudstyr og logsystemer.
- 5. Planlæg levetid og fejl: Test login, logout, tokenfornyelse, gamle faner og flere åbne faner, så sikkerheden ikke bliver omgået for at løse ustabile formularer.
Lad cookie, CORS og Fetch Metadata arbejde som lag
Suppler den primære kontrol med browserens sikkerhedssignaler. De enkelte lag har forskellige undtagelser, så beslut dem samlet og dokumentér de legitime flows, der skal virke på tværs af domæner.
- SameSite: Brug Strict, når brugerrejsen tillader det, eller Lax efter et bevidst valg. None kræver Secure og giver normalt behov for stærkere kontrol af cross-site flows.
- Cookie-afgrænsning: Brug Secure og HttpOnly til sessionscookies, undgå unødigt bred Domain, og begræns Path, når arkitekturen gør det meningsfuldt.
- CORS: Tillad kun kendte origins, metoder og headers. En credentialed request må ikke åbnes bredt, og CORS er ikke i sig selv login eller autorisation.
- Ikke-simple API-requests: Et JSON-API kan kræve en custom header og afvise simple content types, men kun hvis serveren håndhæver kravet og CORS ikke giver fremmede origins adgang.
- Fetch Metadata: Sec-Fetch-Site kan hjælpe serveren med at afvise uventede cross-site ændringer. Hav en kontrolleret fallback for klienter, der ikke sender headeren.
- Origin og Referer: De kan bruges som ekstra kontrol efter frameworkets anbefaling. Sammenlign hele origin-værdien og beslut, hvad der sker, når signalet mangler.
“Same-site” er ikke altid det samme som “same-origin”. En kompromitteret eller fejlkonfigureret underdomænetjeneste kan derfor ændre risikobilledet. Tillad ikke alle same-site requests automatisk uden at vurdere jeres subdomæner og cookiegrænser.
Bevar autorisation og ekstra kontrol ved stor konsekvens
CSRF-kontrollen viser, at requesten kom gennem et forventet browserflow. Den beviser ikke, at brugeren må udføre handlingen. Serveren skal fortsat kontrollere rolle, virksomhed, datapost og tilladte felter på hver request.
- Kræv ny bekræftelse før ændring af loginmetode, e-mail, MFA, betaling, ejer eller administratorrolle.
- Vis det præcise mål og konsekvensen før sletning, massehandlinger og økonomiske dispositioner.
- Brug revisionslog på kritiske handlinger, men log ikke cookies, tokens eller aktive CSRF-værdier.
- Beskyt også login- og logoutflows efter frameworkets model; en uønsket sessionsændring kan forvirre brugeren eller binde handlinger til forkert konto.
Test afslag – ikke kun den grønne vej
En app kan sende en token i alle normale tests, selv om serveren accepterer requests uden den. Negative tests skal derfor kalde endpointet uden om den almindelige brugerflade i et isoleret testmiljø og kontrollere, at ingen sideeffekt sker.
- Send en legitim ændring med korrekt kontrol, og bekræft resultatet.
- Gentag uden token eller krævet header, med forkert værdi og med en værdi fra en anden testsession.
- Forsøg samme handling som en simpel cross-site formularrequest med relevante content types.
- Send requesten fra en ikke-tilladt origin, og kontrollér både preflight og den faktiske backendafvisning.
- Prøv at udløse ændringen med GET og via et indlejret link eller billede; endpointet må ikke ændre tilstand.
- Test gamle faner, tokenfornyelse, logout, flere faner og sessionens udløb uden at slække på serverkontrollen.
- Kontrollér at afviste requests ikke sender mail, starter job, ændrer database eller kalder en leverandør.
- Bekræft at logs viser endpoint, tidspunkt, resultat og sikker requestkontekst uden at gemme hemmeligheder.
Typiske fejl
- Frontend sender en token, men backend validerer den ikke: Kontrollen er pynt og kan udelades af angriberen.
- CORS kaldes CSRF-beskyttelse: Simple formularrequests kan stadig nå serveren, og CORS-regler kan senere blive udvidet.
- SameSite=Lax bliver eneste lag: Loginflow, topnavigation, subdomæner og fremtidige cookieændringer er ikke vurderet.
- GET bruges til “hurtige” handlinger: Links, prefetch, crawlere eller indlejrede ressourcer kan udløse ændringen.
- Kun formularen beskyttes: Mobilendpoints, gamle API-ruter, adminværktøjer og upload/import bliver overset.
- Wildcard og credentials blandes i CORS: Reglerne bliver enten ugyldige eller erstattet af farlig dynamisk origin-refleksion.
- Token ligger i URL'en: Den ender i historik, logs eller referrerdata.
- XSS ignoreres: Kode, der allerede kører i appens origin, kan ofte omgå CSRF-lagene og skal forebygges særskilt.
Tjekliste til CSRF-beskyttelse i en rigtig app
- ☐ Sessionstype og alle steder, hvor browseren automatisk sender credentials, er kortlagt.
- ☐ Alle endpoints med ændrende handlinger, sideeffekter og privilegerede flows er listet.
- ☐ GET, HEAD og OPTIONS ændrer ikke appens tilstand.
- ☐ Frameworkets aktuelle, dokumenterede CSRF-funktion bruges, hvor den findes.
- ☐ Serveren afviser hver beskyttet request, når token eller krævet header mangler eller er ugyldig.
- ☐ Tokens ligger ikke i URL'er, logs, fejlbeskeder eller analyseværktøjer.
- ☐ Sessionscookies har bevidste Secure-, HttpOnly-, SameSite-, Domain- og Path-indstillinger.
- ☐ CORS tillader kun de origins, metoder, headers og credentialed flows, appen faktisk bruger.
- ☐ Fetch Metadata og Origin/Referer er vurderet som supplerende lag med en dokumenteret fallback.
- ☐ Autorisation kontrolleres stadig på serveren for rolle, tenant, objekt og felter.
- ☐ Følsomme ændringer kræver ny bekræftelse eller tydelig brugerinteraktion efter risiko.
- ☐ Negative tests dækker manglende, forkert og fremmed token samt cross-site og simple requests.
- ☐ Afviste requests udfører ingen databaseændring, mail, job eller eksternt kald.
- ☐ Ændringer i login, domæner, proxy, framework og CORS udløser en ny gennemgang.
Relaterede guides
Officielle kilder
Principperne er kontrolleret mod aktuelle webstandarder og sikkerhedsvejledninger. Brug desuden den officielle dokumentation til præcis den framework- og runtimeversion, som jeres app kører på, før I ændrer beskyttelsen i produktion.