Bescherm uw website tegen een veelvoorkomend beveiligingslek met de ingebouwde CSRF-afhandeling van Django.

Django is een Python-webframework waarmee u veilige webapplicaties kunt bouwen. Het biedt veel functies om ontwikkelaars te helpen met beveiliging. Een van deze functies zijn CSRF-tokens, essentieel voor het beschermen van formulieren tegen Cross-Site Request Forgery-aanvallen.

Wat is een CSRF-token?

Een CSRF-token is een beveiligingsfunctie die webapplicaties beschermt tegen Cross-Site Request Forgery (CSRF)-aanvallen. Hiermee kan de applicatieserver controleren of een ingediend formulier afkomstig is van een authentieke browser of dat een hacker het heeft vervalst.

CSRF-tokens zijn formulierinvoer die een gebruikerssessie bijhoudt. Van een website webapplicatieframework aan de serverzijde genereert doorgaans CSRF-tokens voor elke unieke gebruikerssessie. De server controleert of het token correct is wanneer een gebruiker een formulier indient. CSRF-tokens bestaan ​​over het algemeen uit willekeurige reeksen en getallen, waardoor hun waarden onvoorspelbaar zijn.

CSRF-tokengeneratie in Django

van Django get_token() functie genereert willekeurig CSRF-tokens. Om deze functie te vinden, navigeert u naar de csrf.py bestand in uw Python virtuele omgeving. De mappenstructuur zou er als volgt uit moeten zien:

env/

└── Lib/

└── site-pakketten/

└── django/

└── middelware/

└── csrf.py

In dit bestand vindt u de get_token() functie, die het token retourneert. Django gebruikt gegevens maskeren om de waarde van het token te beschermen tegen hackers.

Django schakelt standaard CSRF-beveiliging voor uw site in door toe te voegen django.middleware.csrf. CsrfViewMiddleware in de MIDDELWAREN lijst van je instellingen.py bestand. Het enige wat u hoeft te doen is toevoegen {% csrf_token %} aan jouw NA formulieren. Zonder toe te voegen {% csrf_token %}, je krijgt een 403 verboden) fout bij het verzenden van een formulier.

Wanneer u toevoegt {% csrf_token %} toe aan uw formulier, maakt het automatisch een verborgen invoerveld met de naam csrfmiddlewaretoken, die de waarde van het gemaskeerde CSRF-token bevat. De server gebruikt deze waarde om te bepalen of het ingediende formulier authentiek is. U kunt de waarde van dit verborgen veld controleren door de paginabron te bekijken of door de ontwikkelaarstools van uw browser te gebruiken.

Hoe CSRF-tokens werken in Django

Wanneer u uw site start met het formulier, maakt Django automatisch een browser-cookie genaamd csrftoken. Deze cookie houdt de gebruikersactiviteit op de site bij en identificeert elke gebruiker op unieke wijze.

Wanneer de gebruiker het formulier verzendt, vergelijkt de server de waarde van de cookie met de waarde van de csrfmiddlewaretoken in het verborgen invoerveld. Als deze waarden overeenkomen, zal de server het formulier met succes verwerken, anders zal er een fout optreden.

Op het eerste gezicht zijn de waarden van de cookie en de csrfmiddlewaretoken blijken anders te zijn. Dit is opzettelijk en voegt een extra beschermingslaag toe aan het CSRF-token. Het CSRF-token wordt als volgt vergeleken met de cookie:

  • De get_token() functie maskeert het CSRF-token voordat het wordt doorgegeven aan het invoerveld.
  • Wanneer het formulier wordt verzonden, wordt het CSRF-token ontmaskerd met behulp van de geheime sleutel in het instellingenbestand.
  • Het ontmaskerde token wordt vergeleken met de sessiecookie.
  • Als de waarden hetzelfde zijn, wordt het formulier verwerkt. Als dit niet het geval is, retourneert de server een fout.

Om te voorkomen dat hackers uw CSRF-token stelen, vernieuwt Django het elke keer dat het een gebruikerssessie start.

Aangepaste CSRF-tokens maken

Hoewel Django het gemakkelijk maakt om uw formulieren te beschermen door simpelweg de {% csrf_token %}, het genereren van CSRF-tokens en deze handmatig toevoegen aan uw formulieren is ook mogelijk. Om dit te doen, importeert u de get_token() functie:

van django.middleware.csrf importeren get_token

Naar uw mening kunt u het CSRF-token als volgt genereren:

defbekijk_naam(verzoek):
csrf_token = get_token (verzoek)

# weergavelogica uitvoeren
context = {
"csrf_token": csrf_token
}

opbrengst renderen (verzoek, 'app_naam/sjabloon.html', context=context)

In uw HTML-sjabloon kunt u uw invoertag handmatig opnemen en de csrf_token er zo naar toe:

<formuliermethode="NA" >
<invoertype="verborgen"naam="csrfmiddlewaretoken"waarde="{{ csrf_token }}">
{{form.as_p}}
<knoptype="indienen"klas="btn btn-overzicht-secundair">Boek toevoegenknop>
formulier>

Als alternatief kunt u het verborgen invoerveld als volgt uit uw weergaven genereren:

defjouw zicht(verzoek):
csrf_token = get_token (verzoek)
csrf_token_html = ''.format (csrf_token)

# weergavelogica uitvoeren
context = {
"csrf_token": csrf_token_html
}

opbrengst renderen (verzoek, 'app_naam/sjabloon.html', context=context)

U kunt het dan als volgt aan uw HTML-sjabloon toevoegen:

<formuliermethode="NA" >
{{ csrf_token_html|veilig }}
{{form.as_p}}
<knoptype="indienen"klas="btn btn-overzicht-secundair">Boek toevoegenknop>
formulier>

Als u de CSRF-beveiliging van uw formulier volledig wilt beheren, kunt u dat doen door uw CSRF-token te vergelijken met de cookie die in de browser is opgeslagen. Op basis van de resultaten van de vergelijking kunt u de indiening van het formulier afhandelen zoals u dat wilt. Hier is een voorbeeld:

van django.snelkoppelingen importeren veroorzaken
van django.middleware.csrf importeren get_token, _unmask_cipher_token
van django.utils.crypto importeren constant_time_compare

defjouw zicht(verzoek):
# Genereer een aangepast CSRF-token
csrf_token = get_token (verzoek)
csrf_cookie = verzoek. COOKIES.get('csrfoken')

# csrf-token ontmaskeren
unmasked_csrf_token = _unmask_cipher_token (csrf_token)

# Vergelijk de tokens
alsniet constant_time_compare (unmasked_csrf_token, csrf_cookie):
# Behandel het geval waarin de tokens niet overeenkomen
doorgang
anders:
# Behandel het geval waarin de tokens overeenkomen
doorgang

# Render de sjabloon
context = {
'csrf_token': csrf_token,
}

opbrengst renderen (verzoek, 'app_naam/sjabloon.html', context=context)

Dit codefragment haalt het csrf_cookie van het HTTP-verzoekobject. Het gebruikt dan de _unmask_cipher_token() functie om de csrf_token.

Een voorwaardelijke instructie vergelijkt de waarden van de opgehaalde csrf_cookie en de ontmaskerde csrf_token. Deze vergelijking maakt gebruik van de constant_time_compare functie om te beschermen tegen timing exploits. U kunt uw logica schrijven op basis van het resultaat van de vergelijking.

CSRF-beveiliging uitschakelen in Django

Hoewel Django standaard een voorziening maakt voor CSRF-beveiliging, kunt u deze desgewenst in uw project uitschakelen. Er zijn twee manieren om dit te doen:

  • CSRF-beveiliging op uw hele website uitschakelen.
  • CSRF-beveiliging uitschakelen voor een specifieke weergave.

CSRF-beveiliging uitschakelen op uw hele website

Om de CSRF-beveiliging van Django op uw website uit te schakelen, hoeft u alleen maar de CSRF-middleware uit uw instellingenbestand te verwijderen. Zoek in uw instellingenbestand een lijst met de naam MIDDELWAREN. Zoek in de lijst naar dit:

'django.middleware.csrf. CsrfViewMiddleware',

Zodra je het hebt gevonden, moet je het uit je code verwijderen voor de standaard CSRF-beveiliging van Django om het uit te schakelen.

CSRF-beveiliging uitschakelen voor een specifieke weergave

Als u CSRF-beveiliging alleen op een specifieke Django-weergave wilt uitschakelen, gebruikt u de @csrf_exempt decorateur. Hier is een codefragment om te demonstreren:

van django.views.decorateurs.csrf importeren csrf_vrijgesteld

@csrf_exempt
defbekijk_naam(verzoek):
# weergavelogica uitvoeren
doorgang

De @csrf_exempt decorateur is slechts een van de vele die verband houden met CSRF-bescherming in Django. Over de rest lees je verder Django's CSRF-referentie.

Schakel CSRF-bescherming op uw website niet uit

Hoewel Django het mogelijk maakt, wordt het niet aanbevolen om het ingebouwde CSRF-beveiligingsmechanisme van Django uit te schakelen. Als u dit wel doet, wordt uw site kwetsbaar voor CSRF-aanvallen en heeft dit uiteindelijk negatieve gevolgen voor de gebruikers van uw app.

Tenzij u een ervaren ontwikkelaar bent die weet hoe u een aangepast CSRF-beveiligingsmechanisme moet implementeren, moet u werken met het alternatief van Django.