{"licence":{"name":"CC BY-SA 4.0","spdx":"CC-BY-SA-4.0","url":"https://creativecommons.org/licenses/by-sa/4.0/","attribution":"Atlas, a bilingual technical dictionary (https://cmaintz.github.io/tech-atlas/)"},"id":"security/csrf-token","url":{"en":"https://cmaintz.github.io/tech-atlas/en/terms/security/csrf-token/","da":"https://cmaintz.github.io/tech-atlas/da/terms/security/csrf-token/"},"term":{"en":"CSRF token","da":"CSRF-token"},"aka":{"en":["anti-CSRF token","synchronizer token"],"da":["anti-CSRF-token"]},"domain":["security"],"cluster":"application-security","layer":"application","status":"current","summary":{"en":"A secret, hard-to-guess value a site puts in its own forms and checks on every change, so requests started by other sites fail.","da":"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."},"body":{"formal":{"en":"A random value the server ties to the user's session and places in each page or form it sends; any request that changes data must return the value, and the server refuses requests where it is missing or wrong.","da":"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."},"plain":{"en":"Like a shop that stamps a one-off number on every order form it hands out, and only accepts forms that come back with the number it gave you.","da":"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."},"inPractice":{"en":"A pension fund's member portal puts a hidden field with a fresh value in its form for changing the payout account; a forged change sent from another site carries the login cookie but not the value, so the portal rejects it.","da":"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."},"whyItMatters":{"en":"The browser sends cookies by itself, so a cookie alone cannot prove the user meant to act; without a second proof, any site the user visits can act in their name.","da":"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."}},"deepDive":{"en":"The synchronizer token pattern is the stateful form: the server generates a large unpredictable value with a cryptographically secure random number generator, stores it in the server-side session and embeds it in every form as a hidden field or exposes it to JavaScript through a meta tag. On every unsafe request (POST, PUT, PATCH, DELETE) the server compares the submitted value with the stored one using a constant-time comparison and rejects the request on mismatch or absence. Per-request tokens shorten the window in which a leaked token is useful, and OWASP rates them as more secure, but they break the back button and multiple open tabs, so per-session tokens are the common default.\n\nStateless applications use the double-submit cookie pattern: the token is sent both as a cookie and as a request parameter or header, and the server checks that the two match. The naive version is weak, because an attacker who can write cookies for the domain, for example from a compromised or vulnerable subdomain or through a man-in-the-middle on plain HTTP, can plant a matching pair. OWASP therefore recommends the signed double-submit variant, where the token is an HMAC, keyed with a server secret, over a session-bound value that changes at each login and a random value, so a planted cookie fails verification. Cookie name prefixes such as __Host- further prevent subdomains from overwriting the cookie.\n\nWhere the token travels matters. It must never appear in a URL, since URLs leak through Referer headers, logs and browser history. Single-page applications typically read it from a cookie or an endpoint and send it in a custom header such as X-CSRF-Token or X-XSRF-TOKEN (the convention Angular's HttpClient uses). Frameworks mask the token on each render, XOR-ing it with a fresh random pad as Django and Rails do, so that the value in an HTTPS-compressed response cannot be recovered with a BREACH-style length side channel.\n\nA CSRF token is not an authentication secret and offers no protection against XSS: any script running in the same origin can read it from the DOM. It also does nothing for requests authenticated with a bearer token in an Authorization header, which browsers do not attach automatically, so APIs that do not use cookies usually do not need one. Regenerating the token when the user logs in avoids session fixation-style reuse of a token obtained before authentication.","da":"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.\n\nTilstandslø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.\n\nHvor 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.\n\nEt 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."},"edges":[{"type":"requires","to":"cs/session","confidence":"high","strength":"normal"},{"type":"requires","to":"cs/web-application","confidence":"high","strength":"normal"},{"type":"mitigates","to":"security/cross-site-request-forgery","why":{"en":"A forged request from another site cannot include the value, because that site cannot read the target site's pages.","da":"En forfalsket forespørgsel fra et andet site kan ikke have værdien med, fordi det site ikke kan læse målsitets sider."},"confidence":"high","strength":"primary"},{"type":"used-with","to":"cs/same-origin-policy","confidence":"high","strength":"normal"}],"depth":6,"sources":[{"title":"OWASP Cheat Sheet Series - Cross-Site Request Forgery Prevention","url":"https://cheatsheetseries.owasp.org/cheatsheets/Cross-Site_Request_Forgery_Prevention_Cheat_Sheet.html","tier":"reference","publisher":"OWASP"}],"draft":true}