# Django 6.0.5 documentation

# Skydd mot Cross Site Request Forgery

CSRF middleware och template tag ger ett lättanvänt skydd mot Cross Site Request Forgeries. Denna typ av attack inträffar när en skadlig webbplats innehåller en länk, en formulärknapp eller JavaScript som är avsedd att utföra någon åtgärd på din webbplats med hjälp av inloggningsuppgifterna för en inloggad användare som besöker den skadliga webbplatsen i sin webbläsare. En relaterad typ av attack, ”login CSRF”, där en angripande webbplats lurar en användares webbläsare att logga in på en webbplats med någon annans inloggningsuppgifter, omfattas också.

Det första försvaret mot CSRF-attacker är att se till att GET-begäranden (och andra ”säkra” metoder, enligt definitionen i RFC 9110 Section 9.2.1) är bieffektsfria. Förfrågningar via ”osäkra” metoder, som POST, PUT och DELETE, kan sedan skyddas genom de steg som beskrivs i Så här använder du Djangos CSRF-skydd.

## Hur det fungerar

CSRF-skyddet baseras på följande saker:

1. En CSRF-cookie som är ett slumpmässigt hemligt värde, som andra webbplatser inte har tillgång till.

   `CsrfViewMiddleware` skickar denna cookie med svaret när `django.middleware.csrf.get_token()` anropas. Den kan också skicka den i andra fall. Av säkerhetsskäl ändras värdet på hemligheten varje gång en användare loggar in.

2. Ett dolt formulärfält med namnet ”csrfmiddlewaretoken”, som finns i alla utgående POST-formulär.

   För att skydda mot BREACH-attacker är värdet i detta fält inte bara hemligheten. Det krypteras på olika sätt för varje svar med hjälp av en mask. Masken genereras slumpmässigt vid varje anrop till `get_token()`, så formulärfältets värde är olika varje gång.

   Denna del görs av `csrf_token` malltagg.

3. För alla inkommande förfrågningar som inte använder HTTP GET, HEAD, OPTIONS eller TRACE måste en CSRF-cookie finnas och fältet ”csrfmiddlewaretoken” måste finnas och vara korrekt. Om så inte är fallet kommer användaren att få ett 403-fel.

   Vid validering av fältvärdet ”csrfmiddlewaretoken” jämförs endast hemligheten, inte hela token, med hemligheten i cookie-värdet. Detta gör det möjligt att använda ständigt föränderliga token. Även om varje begäran kan använda sin egen token förblir hemligheten gemensam för alla.

   Denna kontroll görs av `CsrfViewMiddleware`.

4. `CsrfViewMiddleware` verifierar Origin header, om det tillhandahålls av webbläsaren, mot den aktuella värden och inställningen `CSRF_TRUSTED_ORIGINS`. Detta ger skydd mot attacker över flera underdomäner.

5. Dessutom, för HTTPS-förfrågningar, om `Origin`-headern inte tillhandahålls, utför `CsrfViewMiddleware` strikt referer-kontroll. Detta innebär att även om en underdomän kan ställa in eller ändra cookies på din domän, kan den inte tvinga en användare att posta till din applikation eftersom den begäran inte kommer från din egen exakta domän.

   Detta hanterar också en man-in-the-middle-attack som är möjlig under HTTPS när en sessionsoberoende hemlighet används, på grund av att HTTP `Set-Cookie`-rubriker (tyvärr) accepteras av klienter även när de pratar med en webbplats under HTTPS. (Referer-kontroll görs inte för HTTP-förfrågningar eftersom närvaron av `Referer`-rubriken inte är tillräckligt tillförlitlig under HTTP)

   Om inställningen `CSRF_COOKIE_DOMAIN` är angiven jämförs referensen mot den. Du kan tillåta förfrågningar över underdomäner genom att inkludera en inledande punkt. Till exempel: kommer `CSRF_COOKIE_DOMAIN = '.example.com'` att tillåta POST-förfrågningar från `www.example.com` och `api.example.com`. Om inställningen inte är angiven måste referensen matcha HTTP-rubriken `Host`.

   Att utöka de accepterade referenserna utöver den aktuella värd- eller cookiedomänen kan göras med inställningen `CSRF_TRUSTED_ORIGINS`.

Detta säkerställer att endast formulär som kommer från betrodda domäner kan användas för att skicka tillbaka data.

Den ignorerar avsiktligt GET-begäranden (och andra begäranden som definieras som ”säkra” av RFC 9110 Section 9.2.1). Dessa förfrågningar borde aldrig ha några potentiellt farliga bieffekter, och därför borde en CSRF-attack med en GET-förfrågan vara ofarlig. RFC 9110 Section 9.2.1 definierar POST, PUT och DELETE som ”osäkra”, och alla andra metoder antas också vara osäkra, för maximalt skydd.

CSRF-skyddet kan inte skydda mot man-in-the-middle-attacker, så använd HTTPS med HTTP Strict Transport Security. Det förutsätter också validering av HOST-headern och att det inte finns några cross-site scripting-sårbarheter på din webbplats (eftersom XSS-sårbarheter redan låter en angripare göra allt som en CSRF-sårbarhet tillåter och mycket värre).

Ta bort rubriken `Referer`

För att undvika att avslöja referentens URL till tredjepartswebbplatser kanske du vill inaktivera referenten på webbplatsens `<a>`-taggar. Du kan till exempel använda taggen `<meta name="referrer" content="no-referrer">` eller inkludera rubriken `Referrer-Policy: no-referrer`. På grund av CSRF-skyddets strikta referer-kontroll på HTTPS-förfrågningar orsakar dessa tekniker ett CSRF-misslyckande på förfrågningar med ”osäkra” metoder. Använd istället alternativ som `<a rel="noreferrer" ...>"` för länkar till tredjepartswebbplatser.

## Begränsningar

Underdomäner inom en webbplats kommer att kunna ställa in cookies på klienten för hela domänen. Genom att ställa in cookien och använda en motsvarande token kan underdomäner kringgå CSRF-skyddet. Det enda sättet att undvika detta är att se till att underdomäner kontrolleras av betrodda användare (eller åtminstone inte kan ställa in cookies). Observera att även utan CSRF finns det andra sårbarheter, t.ex. sessionsfixering, som gör att det är en dålig idé att ge underdomäner till icke betrodda parter, och dessa sårbarheter kan inte enkelt åtgärdas med nuvarande webbläsare.

## Verktyg

Exemplen nedan förutsätter att du använder funktionsbaserade vyer. Om du arbetar med klassbaserade vyer kan du läsa Dekorera klassbaserade vyer.

csrf_exempt(view)

  Denna dekorator markerar att en vy är undantagen från det skydd som säkerställs av mellanvaran. Exempel:

      from django.http import HttpResponse
      from django.views.decorators.csrf import csrf_exempt

      @csrf_exempt
      def my_view(request):
          return HttpResponse("Hello world")

csrf_protect(view)

  Dekoratör som ger skydd av `CsrfViewMiddleware` till en vy.

  Användning:

      from django.shortcuts import render
      from django.views.decorators.csrf import csrf_protect

      @csrf_protect
      def my_view(request):
          c = {}
          # ...
          return render(request, "a_template.html", c)

requires_csrf_token(view)

  Normalt fungerar inte malltaggen `csrf_token` om inte `CsrfViewMiddleware.process_view` eller motsvarande som `csrf_protect` har körts. Vydekoratorn `requires_csrf_token` kan användas för att säkerställa att malltaggen fungerar. Denna dekorator fungerar på liknande sätt som `csrf_protect`, men avvisar aldrig en inkommande begäran.

  Exempel:

      from django.shortcuts import render
      from django.views.decorators.csrf import requires_csrf_token

      @requires_csrf_token
      def my_view(request):
          c = {}
          # ...
          return render(request, "a_template.html", c)

ensure_csrf_cookie(view)

  Denna dekorator tvingar en vy att skicka CSRF-cookien.

## Inställningar

Ett antal inställningar kan användas för att styra Djangos CSRF-beteende:

- `CSRF_COOKIE_AGE`

- `CSRF_COOKIE_DOMAIN`

- `CSRF_COOKIE_HTTPONLY`

- `CSRF_COOKIE_NAME`

- `CSRF_COOKIE_PATH`

- `CSRF_COOKIE_SAMESITE`

- `CSRF_COOKIE_SECURE`

- `CSRF_FAILURE_VIEW`

- `CSRF_HEADER_NAME`

- `CSRF_TRUSTED_ORIGINS`

- `CSRF_USE_SESSIONS`

## Vanliga frågor

### Är det en sårbarhet att lägga upp ett godtyckligt CSRF-tokenpar (cookie och POST-data)?

Nej, detta är avsiktligt. Utan en man-in-the-middle-attack finns det inget sätt för en angripare att skicka en CSRF-token-cookie till ett offers webbläsare, så en framgångsrik attack skulle behöva få offrets webbläsares cookie via XSS eller liknande, i vilket fall en angripare vanligtvis inte behöver CSRF-attacker.

Vissa säkerhetsgranskningsverktyg flaggar detta som ett problem, men som nämnts tidigare kan en angripare inte stjäla en användares webbläsares CSRF-cookie. att ”stjäla” eller modifiera * din egen * token med Firebug, Chrome dev tools, etc. är inte en sårbarhet.

### Är det ett problem att Djangos CSRF-skydd inte är kopplat till en session som standard?

Nej, detta är avsiktligt. Att inte koppla CSRF-skydd till en session gör det möjligt att använda skyddet på webbplatser som en pastebin som tillåter inskick från anonyma användare som inte har en session.

Om du vill lagra CSRF-token i användarens session ska du använda inställningen `CSRF_USE_SESSIONS`.

### Varför kan en användare stöta på ett CSRF-valideringsfel efter att ha loggat in?

Av säkerhetsskäl roteras CSRF-tokens varje gång en användare loggar in. Alla sidor med ett formulär som genereras före en inloggning kommer att ha en gammal, ogiltig CSRF-token och måste laddas om. Detta kan hända om en användare använder bakåtknappen efter en inloggning eller om de loggar in i en annan webbläsarflik.