Beskyt din hjemmeside mod et meget almindeligt sikkerhedshul med Djangos indbyggede CSRF-håndtering.

Django er en Python-webramme, du kan bruge til at bygge sikre webapplikationer. Det tilbyder mange funktioner til at hjælpe udviklere med sikkerhed. En af disse funktioner er CSRF-tokens, som er afgørende for at beskytte formularer mod Cross-Site Request Forgery-angreb.

Hvad er et CSRF-token?

Et CSRF-token er en sikkerhedsfunktion, der beskytter webapplikationer mod Cross-Site Request Forgery (CSRF) angreb. Det giver applikationsserveren mulighed for at kontrollere, om en formularindsendelse kom fra en autentisk browser, eller om en hacker har forfalsket den.

CSRF-tokens er formularinput, der holder styr på en brugersession. En hjemmeside server-side webapplikationsramme genererer typisk CSRF-tokens for hver unik brugersession. Serveren kontrollerer, om tokenet er korrekt, hver gang en bruger indsender en formular. CSRF-tokens består generelt af tilfældige strenge og tal, hvilket gør deres værdier uforudsigelige.

instagram viewer

CSRF Token Generation i Django

Django's get_token() funktion genererer tilfældigt CSRF-tokens. For at finde denne funktion skal du navigere til csrf.py fil inde i din Python virtuelt miljø. Mappestrukturen skulle se sådan ud:

env/

└── Lib/

└── site-pakker/

└── django/

└── middleware/

└── csrf.py

Inde i denne fil finder du get_token() funktion, som returnerer tokenet. Django bruger datamaskering for at beskytte tokens værdi mod hackere.

Som standard aktiverer Django CSRF-beskyttelse for dit websted ved at tilføje django.middleware.csrf. CsrfViewMiddleware i MIDDELVARE din liste settings.py fil. Alt du skal gøre er at tilføje {% csrf_token %} til din STOLPE formularer. Uden at tilføje {% csrf_token %}, du får en 403 forbudt) fejl, når du indsender en formular.

Når du tilføjer {% csrf_token %} til din formular, opretter den automatisk et skjult inputfelt med navnet csrfmiddlewaretoken, som indeholder værdien af ​​det maskerede CSRF-token. Serveren bruger denne værdi til at bestemme, om formularindsendelsen er autentisk. Du kan kontrollere værdien af ​​dette skjulte felt ved at se sidekilden eller bruge din browsers udviklerværktøjsfunktion.

Sådan fungerer CSRF-tokens i Django

Når du starter dit websted med formularen, opretter Django automatisk en browser-cookie hedder csrftoken. Denne cookie holder styr på brugeraktivitet på webstedet og identificerer entydigt hver bruger.

Når brugeren indsender formularen, sammenligner serveren værdien af ​​cookien med værdien af csrfmiddlewaretoken i det skjulte indtastningsfelt. Hvis disse værdier matcher, vil serveren behandle formularen med succes, ellers vil den producere en fejl.

Ved første øjekast er værdierne af cookien og csrfmiddlewaretoken synes at være anderledes. Dette er bevidst og tilføjer et ekstra lag af beskyttelse til CSRF-tokenet. CSRF-tokenet bliver sammenlignet med cookien på denne måde:

  • Det get_token() funktionen maskerer CSRF-tokenet, før det sendes videre til inputfeltet.
  • Når formularen indsendes, afsløres CSRF-tokenet ved hjælp af den hemmelige nøgle i indstillingsfilen.
  • Det umaskerede token bliver sammenlignet med sessionscookien.
  • Hvis værdierne er de samme, bliver formularen behandlet. Hvis ikke, returnerer serveren en fejl.

For at forhindre hackere i at stjæle dit CSRF-token, fornyer Django det, hver gang det starter en brugersession.

Oprettelse af brugerdefinerede CSRF-tokens

Selvom Django gør det nemt at beskytte dine formularer ved blot at tilføje {% csrf_token %}, at generere CSRF-tokens og manuelt tilføje dem til dine formularer er også muligt. For at gøre dette skal du importere get_token() fungere:

fra django.middleware.csrf importere get_token

Efter din mening kan du generere CSRF-tokenet sådan her:

defview_name(anmodning):
csrf_token = get_token (anmodning)

# udfør visningslogik
kontekst = {
"csrf_token": csrf_token
}

Vend tilbage gengive (anmodning, 'app_name/template.html', kontekst=kontekst)

I din HTML-skabelon kan du manuelt inkludere dit input-tag og tilføje csrf_token til det sådan her:

<formmetode="STOLPE" >
<inputtype="skjult"navn="csrfmiddlewaretoken"værdi="{{ csrf_token }}">
{{form.as_p}}
<knaptype="Indsend"klasse="btn btn-outline-sekundær">Tilføj bogknap>
form>

Alternativt kan du generere det skjulte inputfelt fra dine visninger som dette:

defdit_syn(anmodning):
csrf_token = get_token (anmodning)
csrf_token_html = ''.format (csrf_token)

# udfør visningslogik
kontekst = {
"csrf_token": csrf_token_html
}

Vend tilbage gengive (anmodning, 'app_name/template.html', kontekst=kontekst)

Du kan derefter tilføje det til din HTML-skabelon på denne måde:

<formmetode="STOLPE" >
{{ csrf_token_html|sikker }}
{{form.as_p}}
<knaptype="Indsend"klasse="btn btn-outline-sekundær">Tilføj bogknap>
form>

Hvis du vil have fuldstændig kontrol over din formulars CSRF-beskyttelse, kan du gøre det ved at sammenligne dit CSRF-token med den cookie, der er gemt i browseren. Baseret på resultaterne af sammenligningen kan du håndtere formularindsendelsen, som du vil. Her er et eksempel:

fra django.genveje importere gengive
fra django.middleware.csrf importere get_token, _unmask_cipher_token
fra django.utils.crypto importere konstant_tid_sammenlign

defdit_syn(anmodning):
# Generer et brugerdefineret CSRF-token
csrf_token = get_token (anmodning)
csrf_cookie = anmodning. COOKIES.get('csrftoken')

# afmaske csrf-token
unmasked_csrf_token = _unmask_cipher_token (csrf_token)

# Sammenlign tokens
hvisikke constant_time_compare (unmasked_csrf_token, csrf_cookie):
# Håndter sagen, hvor tokens ikke matcher
passere
andet:
# Håndter sagen, hvor tokens matcher
passere

# Gengiv skabelonen
kontekst = {
'csrf_token': csrf_token,
}

Vend tilbage gengive (anmodning, 'app_name/template.html', kontekst=kontekst)

Dette kodestykke henter csrf_cookie fra HTTP-anmodningsobjektet. Den bruger så _unmask_cipher_token() funktion til at afmaske csrf_token.

En betinget erklæring sammenligner værdierne af det hentede csrf_cookie og de afmaskede csrf_token. Denne sammenligning bruger konstant_tid_sammenlign funktion til at beskytte mod timing exploits. Du kan skrive din logik ud fra resultatet af sammenligningen.

Deaktivering af CSRF-beskyttelse i Django

Selvom Django laver en standardbestemmelse for CSRF-beskyttelse, kan du deaktivere den i dit projekt, hvis du vil. Der er to måder at gøre dette på:

  • Deaktivering af CSRF-beskyttelse på hele dit websted.
  • Deaktivering af CSRF-beskyttelse på en bestemt visning.

Deaktivering af CSRF-beskyttelse på hele dit websted

For at deaktivere Djangos CSRF-beskyttelse på dit websted, skal du blot fjerne CSRF-middlewaren fra din indstillingsfil. Find en liste med navnet i din indstillingsfil MIDDELVARE. Søg efter dette inde i listen:

'django.middleware.csrf. CsrfViewMiddleware',

Når du har fundet det, skal du fjerne det fra din kode for at Djangos standard CSRF-beskyttelse kan deaktivere det.

Deaktivering af CSRF-beskyttelse på en bestemt visning

Hvis du kun ønsker at deaktivere CSRF-beskyttelse på en specifik Django-visning, skal du bruge @csrf_fritaget dekoratør. Her er et kodestykke til at demonstrere:

fra django.views.decorators.csrf importere csrf_fritaget

@csrf_fritaget
defview_name(anmodning):
# udfør visningslogik
passere

Det @csrf_fritaget decorator er blot en af ​​flere relateret til CSRF-beskyttelse i Django. Du kan læse om resten på Djangos CSRF reference.

Deaktiver ikke CSRF-beskyttelse på dit websted

Selvom Django gør det muligt, anbefales det ikke at deaktivere Djangos indbyggede CSRF-beskyttelsesmekanisme. Hvis du gør det, vil dit websted blive sårbart over for CSRF-angreb og i sidste ende påvirke brugerne af din app negativt.

Medmindre du er en erfaren udvikler, der ved, hvordan man implementerer en tilpasset CSRF-beskyttelsesmekanisme, bør du arbejde med alternativet fra Django.