Beskytt nettstedet ditt mot et veldig vanlig sikkerhetshull med Djangos innebygde CSRF-håndtering.

Django er et Python-nettrammeverk du kan bruke til å bygge sikre webapplikasjoner. Den tilbyr mange funksjoner for å hjelpe utviklere med sikkerhet. En av disse funksjonene er CSRF-tokens, essensielle for å beskytte skjemaer fra Cross-Site Request Forgery-angrep.

Hva er et CSRF-token?

Et CSRF-token er en sikkerhetsfunksjon som beskytter webapplikasjoner mot Cross-Site Request Forgery (CSRF) angrep. Den lar applikasjonsserveren sjekke om en skjemainnsending kom fra en autentisk nettleser eller en hacker har forfalsket den.

CSRF-tokens er skjemainndata som holder styr på en brukerøkt. Et nettsted server-side webapplikasjonsrammeverk genererer vanligvis CSRF-tokens for hver unike brukerøkt. Serveren sjekker om tokenet er riktig hver gang en bruker sender inn et skjema. CSRF-tokens består vanligvis av tilfeldige strenger og tall, noe som gjør verdiene uforutsigbare.

Generering av CSRF-token i Django

instagram viewer

Django sin get_token() funksjonen genererer tilfeldig CSRF-tokens. For å finne denne funksjonen, naviger til csrf.py fil inne i din Python virtuelt miljø. Mappestrukturen skal se slik ut:

env/

└── Lib/

└── nettsted-pakker/

└── django/

└── mellomvare/

└── csrf.py

Inne i denne filen finner du get_token() funksjon, som returnerer tokenet. Django bruker datamaskering for å beskytte tokens verdi mot hackere.

Som standard aktiverer Django CSRF-beskyttelse for nettstedet ditt ved å legge til django.middleware.csrf. CsrfViewMiddleware i MIDDELVARE listen over dine settings.py fil. Alt du trenger å gjøre er å legge til {% csrf_token %} til din POST skjemaer. Uten å legge til {% csrf_token %}, du vil få en 403 Forbudt) feil når du sender inn et skjema.

Når du legger til {% csrf_token %} til skjemaet ditt oppretter det automatisk et skjult inndatafelt med navnet csrfmiddlewaretoken, som inneholder verdien til det maskerte CSRF-tokenet. Serveren bruker denne verdien for å avgjøre om skjemainnsendingen er autentisk. Du kan sjekke verdien av dette skjulte feltet ved å se sidekilden eller bruke nettleserens utviklerverktøyfunksjon.

Hvordan CSRF-tokens fungerer i Django

Når du starter nettstedet ditt med skjemaet, oppretter Django automatisk en nettleserinformasjonskapsel kalt csrftoken. Denne informasjonskapselen holder oversikt over brukeraktivitet på nettstedet og identifiserer hver bruker unikt.

Når brukeren sender inn skjemaet, sammenligner serveren verdien av informasjonskapselen med verdien av csrfmiddlewaretoken i det skjulte inndatafeltet. Hvis disse verdiene samsvarer, vil serveren behandle skjemaet vellykket, ellers vil det gi en feil.

Ved første øyekast kan verdiene til informasjonskapselen og csrfmiddlewaretoken ser ut til å være annerledes. Dette er med vilje og legger til et ekstra lag med beskyttelse til CSRF-tokenet. CSRF-tokenet blir sammenlignet med informasjonskapselen slik:

  • De get_token() funksjonen maskerer CSRF-tokenet før det sendes videre til inndatafeltet.
  • Når skjemaet sendes, blir CSRF-tokenet demaskert ved hjelp av den hemmelige nøkkelen i innstillingsfilen.
  • Det demaskerte tokenet blir sammenlignet med øktinformasjonskapselen.
  • Hvis verdiene er de samme, blir skjemaet behandlet. Hvis ikke, returnerer serveren en feil.

For å hindre hackere i å stjele CSRF-tokenet ditt, fornyer Django det hver gang det starter en brukerøkt.

Opprette egendefinerte CSRF-tokens

Selv om Django gjør det enkelt å beskytte skjemaene dine ved å legge til {% csrf_token %}, å generere CSRF-tokens og legge dem til manuelt i skjemaene dine er også mulig. For å gjøre dette, importer get_token() funksjon:

fra django.middleware.csrf import get_token

Etter ditt syn kan du generere CSRF-tokenet slik:

defview_name(be om):
csrf_token = get_token (forespørsel)

# utfør visningslogikk
kontekst = {
"csrf_token": csrf_token
}

komme tilbake gjengi (forespørsel, 'app_name/template.html', kontekst=kontekst)

I HTML-malen din kan du manuelt inkludere input-taggen og legge til csrf_token til det slik:

<formmetode="POST" >
<inputtype="skjult"Navn="csrfmiddlewaretoken"verdi="{{ csrf_token }}">
{{form.as_p}}
<knapptype="sende inn"klasse="btn btn-outline-sekundær">Legg til bokknapp>
form>

Alternativt kan du generere det skjulte inndatafeltet fra visningene dine slik:

defdin_visning(be om):
csrf_token = get_token (forespørsel)
csrf_token_html = ''.format (csrf_token)

# utfør visningslogikk
kontekst = {
"csrf_token": csrf_token_html
}

komme tilbake gjengi (forespørsel, 'app_name/template.html', kontekst=kontekst)

Du kan deretter legge den til HTML-malen din slik:

<formmetode="POST" >
{{ csrf_token_html|safe }}
{{form.as_p}}
<knapptype="sende inn"klasse="btn btn-outline-sekundær">Legg til bokknapp>
form>

Hvis du vil kontrollere skjemaets CSRF-beskyttelse fullstendig, kan du gjøre det ved å sammenligne CSRF-tokenet ditt med informasjonskapselen som er lagret i nettleseren. Basert på resultatene av sammenligningen kan du håndtere skjemainnsendingen slik du vil. Her er et eksempel:

fra django.snarveier import gjengi
fra django.middleware.csrf import get_token, _unmask_cipher_token
fra django.utils.crypto import konstant_tid_sammenlign

defdin_visning(be om):
# Generer et tilpasset CSRF-token
csrf_token = get_token (forespørsel)
csrf_cookie = forespørsel. COOKIES.get('csrftoken')

# avmaske csrf-token
unmasked_csrf_token = _unmask_cipher_token (csrf_token)

# Sammenlign symbolene
hvisikke constant_time_compare (unmasked_csrf_token, csrf_cookie):
# Håndter saken der tokenene ikke stemmer overens
sende
ellers:
# Håndter saken der tokens matcher
sende

# Gjengi malen
kontekst = {
'csrf_token': csrf_token,
}

komme tilbake gjengi (forespørsel, 'app_name/template.html', kontekst=kontekst)

Denne kodebiten henter csrf_cookie fra HTTP-forespørselsobjektet. Den bruker da _unmask_cipher_token() funksjon for å demaskere csrf_token.

Et betinget utsagn sammenligner verdiene til det hentede csrf_cookie og de avmaskede csrf_token. Denne sammenligningen bruker konstant_tid_sammenlign funksjon for å beskytte mot tidsutnyttelse. Du kan skrive logikken din basert på resultatet av sammenligningen.

Deaktivering av CSRF-beskyttelse i Django

Selv om Django har en standardbestemmelse for CSRF-beskyttelse, kan du deaktivere den i prosjektet ditt hvis du vil. Det er to måter å gjøre dette på:

  • Deaktivering av CSRF-beskyttelse på hele nettstedet ditt.
  • Deaktivering av CSRF-beskyttelse på en bestemt visning.

Deaktivering av CSRF-beskyttelse på hele nettstedet ditt

For å deaktivere Djangos CSRF-beskyttelse på nettstedet ditt, må du ganske enkelt fjerne CSRF-mellomvaren fra innstillingsfilen din. I innstillingsfilen din, finn en liste som heter MIDDELVARE. Inne i listen, søk etter dette:

'django.middleware.csrf. CsrfViewMiddleware',

Når du finner den, bør du fjerne den fra koden din for Djangos standard CSRF-beskyttelse for å deaktivere den.

Deaktivering av CSRF-beskyttelse på en bestemt visning

Hvis du bare vil deaktivere CSRF-beskyttelse på en bestemt Django-visning, bruk @csrf_exempt dekoratør. Her er en kodebit for å demonstrere:

fra django.views.decorators.csrf import csrf_exempt

@csrf_exempt
defview_name(be om):
# utfør visningslogikk
sende

De @csrf_exempt decorator er bare en av flere relatert til CSRF-beskyttelse i Django. Resten kan du lese om på Djangos CSRF-referanse.

Ikke deaktiver CSRF-beskyttelse på nettstedet ditt

Selv om Django gjør det mulig, anbefales det ikke å deaktivere Djangos innebygde CSRF-beskyttelsesmekanisme. Å gjøre det vil gjøre nettstedet ditt sårbart for CSRF-angrep og til slutt påvirke brukerne av appen din negativt.

Med mindre du er en erfaren utvikler som vet hvordan du implementerer en tilpasset CSRF-beskyttelsesmekanisme, bør du jobbe med alternativet som tilbys av Django.