Gå til indhold
atlas

CSRF-token

Også kendt som: anti-CSRF-token

En hemmelig værdi, som et site lægger i sine egne formularer og tjekker ved hver ændring, så forespørgsler fra andre sites afvises.

Kladde - dette opslag er endnu ikke gennemgået.

Formelt

En tilfældig værdi, som serveren knytter til brugerens session og lægger i hver side eller formular, den sender; enhver forespørgsel, der ændrer data, skal sende værdien tilbage, og serveren afviser forespørgsler, hvor den mangler eller er forkert.

Forklaret enkelt

Som en butik, der stempler et engangsnummer på hver bestillingsseddel, den udleverer, og kun godtager sedler, der kommer tilbage med det nummer, den gav dig.

I praksis

En pensionskasses medlemsportal lægger et skjult felt med en ny værdi i formularen til at ændre udbetalingskonto; en forfalsket ændring fra et andet site har cookien fra login med, men ikke værdien, så portalen afviser den.

Hvorfor det betyder noget

Browseren sender selv cookies med, så en cookie alene beviser ikke, at brugeren ville handle; uden et ekstra bevis kan ethvert site, brugeren besøger, handle i vedkommendes navn.

Sådan kommer du i gang

De typiske trin i rækkefølge. Tilpas dem til jeres organisation.

  1. Lav en liste over alle forespørgsler, der ændrer tilstand (POST, PUT, PATCH, DELETE), og sørg for, at ingen GET-forespørgsel ændrer data.
  2. Slå frameworkets indbyggede CSRF-beskyttelse til, fx anti-forgery tokens i ASP.NET Core, Django eller Spring Security, i stedet for at skrive jeres egen.
  3. Generér tokenet med en kryptografisk sikker tilfældighedsgenerator, knyt det til brugerens session, og udsted et nyt, når brugeren logger ind.
  4. Læg tokenet i et skjult formularfelt eller, i en single page-app, send det i en brugerdefineret header som X-CSRF-Token, og læg det aldrig i en URL.
  5. Tjek tokenet på serveren ved hver forespørgsel, der ændrer tilstand, med en sammenligning i konstant tid, og afvis forespørgslen, hvis det mangler eller er forkert.
  6. Er applikationen tilstandsløs, så brug den signerede double-submit-cookie med en HMAC bundet til sessionen, og giv cookien præfikset __Host-.
  7. Tilføj et ekstra forsvarslag med SameSite=Lax eller Strict på sessionscookies og et tjek af Fetch Metadata- eller Origin-headers på usikre forespørgsler.
  8. Test, at en forfalsket forespørgsel fra en anden origin bliver afvist, og hold testen i den automatiske testsuite, så et nyt endpoint ikke kan springe tjekket over.

Typiske faldgruber

  • At undtage enkelte endpoints, fx JSON- eller upload-endpoints, fra CSRF-tjekket for at få en klient til at virke.
  • At bruge den naive double-submit-cookie uden signatur, som en angriber med kontrol over et subdomæne kan omgå.
  • At stole på SameSite-cookies alene, selv om forespørgsler fra søster-subdomæner tæller som same-site og stadig slipper igennem.
  • At tro, at tokenet hjælper mod XSS, når ethvert script, der kører på siden, kan læse det.

Gode vejledninger

Teknisk uddybning

Synchronizer token-mønstret er den tilstandsfulde form: serveren genererer en stor, uforudsigelig værdi med en kryptografisk sikker tilfældighedsgenerator, gemmer den i sessionen på serversiden og indlejrer den i hver formular som skjult felt eller gør den tilgængelig for JavaScript via et meta-tag. Ved hver usikker forespørgsel (POST, PUT, PATCH, DELETE) sammenligner serveren den indsendte værdi med den gemte med en sammenligning i konstant tid og afviser forespørgslen, hvis værdien mangler eller ikke passer. Tokens pr. forespørgsel forkorter det tidsrum, hvor et lækket token kan bruges, og OWASP vurderer dem som mere sikre, men de ødelægger tilbageknappen og flere åbne faner, så tokens pr. session er det almindelige valg.

Tilstandsløse applikationer bruger double-submit-cookie-mønstret: tokenet sendes både som cookie og som parameter eller header, og serveren tjekker, at de to er ens. Den naive udgave er svag, fordi en angriber, der kan skrive cookies til domænet, fx fra et kompromitteret eller sårbart subdomæne eller via man-in-the-middle på ukrypteret HTTP, kan plante et matchende par. OWASP anbefaler derfor den signerede variant, hvor tokenet er en HMAC med en hemmelig servernøgle over en sessionsbundet værdi, der skifter ved hvert login, og en tilfældig værdi, så en plantet cookie ikke består verifikationen. Cookie-præfikser som __Host- forhindrer desuden subdomæner i at overskrive cookien.

Hvor tokenet sendes, har betydning. Det må aldrig stå i en URL, da URL'er lækker via Referer-headers, logs og browserhistorik. Single page-applikationer læser det typisk fra en cookie eller et endpoint og sender det i en brugerdefineret header som X-CSRF-Token eller X-XSRF-TOKEN (den konvention, Angulars HttpClient bruger). Frameworks maskerer tokenet ved hver rendering, hvor det XOR'es med en ny tilfældig værdi, som Django og Rails gør, så værdien i et komprimeret HTTPS-svar ikke kan genskabes via en længdebaseret sidekanal af BREACH-typen.

Et CSRF-token er ikke en autentificeringshemmelighed og beskytter ikke mod XSS: ethvert script, der kører i samme origin, kan læse det fra DOM'en. Det gør heller intet for forespørgsler, der autentificeres med et bearer token i Authorization-headeren, fordi browsere ikke sender den med automatisk, så API'er uden cookies har som regel ikke brug for et. At generere et nyt token, når brugeren logger ind, forhindrer, at et token hentet før autentificering genbruges på samme måde som ved session fixation.

Hvad du bør lære først

Alt det, dette bygger på - grundlaget først.

  1. Digital identitet
  2. →Netværk
  3. →Loginoplysning (credential)
  4. →IP-adresse
  5. →Protokol
  6. →Autentificering
  7. →Klient
  8. →Pakke
  9. →Port
  10. →Server
  11. →Session
  12. →TCP/IP
  13. →HTTP
  14. →Webapplikation
  15. →CSRF-token

Relationer

Bruges sammen med
Same-origin policy

Kilder og videre læsning

Hvor dataene kommer fra

Dette opslag er skrevet af en AI ud fra kilderne ovenfor og er endnu ikke gennemgået af et menneske. Brug det som udgangspunkt, og tjek alt vigtigt mod kilderne.

Se gennemgangskøenForeslå en rettelse på GitHubDette begreb som JSON

Test dig selv

Indlæser…

Atlas er i beta.