Django est un framework web Python que vous pouvez utiliser pour construire des applications web sécurisées. Il offre de nombreuses fonctionnalités pour aider les développeurs en matière de sécurité. L’une de ces fonctionnalités est le jeton CSRF, essentiel pour protéger les formulaires contre les attaques de type Cross-Site Request Forgery.
Qu’est-ce qu’un jeton CSRF ?
Un jeton CSRF est un dispositif de sécurité qui protège les applications web contre les attaques de type Cross-Site Request Forgery (CSRF). Il permet au serveur d’application de vérifier si la soumission d’un formulaire provient d’un navigateur authentique ou si elle a été falsifiée par un pirate.
Les jetons CSRF sont des entrées de formulaire qui permettent de suivre la session d’un utilisateur. Le cadre d’application web côté serveur d’un site web génère généralement des jetons CSRF pour chaque session utilisateur unique. Le serveur vérifie si le jeton est correct chaque fois qu’un utilisateur soumet un formulaire. Les jetons CSRF sont généralement constitués de chaînes et de nombres aléatoires, ce qui rend leurs valeurs imprévisibles.
Génération de jetons CSRF dans Django
La fonction get_token() La fonction get_token génère aléatoirement des jetons CSRF. Pour trouver cette fonction, naviguez jusqu’à la page csrf.py dans votre environnement virtuel Python. La structure du dossier doit ressembler à ceci :
env/
└── Lib/
└── site-packages/
└── django/
└── middleware/
└── csrf.py
À l’intérieur de ce fichier, vous trouverez le fichier get_token() qui renvoie le jeton. Django utilise le masquage des données pour protéger la valeur du jeton contre les pirates.
Par défaut, Django active la protection CSRF pour votre site en ajoutant la fonction django.middleware.csrf.CsrfViewMiddleware dans le fichier LOGICIEL MIXTE liste de vos settings.py . Tout ce que vous avez à faire est d’ajouter {% csrf_token %} à votre POST formes. Sans ajouter {% csrf_token %}, vous obtiendrez un 403 (interdit) lorsque vous soumettez un formulaire.
Lorsque vous ajoutez {% csrf_token %} à votre formulaire, il crée automatiquement un champ de saisie caché avec le nom csrfmiddlewaretokenqui contient la valeur du jeton CSRF masqué. Le serveur utilise cette valeur pour déterminer si la soumission du formulaire est authentique. Vous pouvez vérifier la valeur de ce champ caché en consultant la source de la page ou en utilisant les outils de développement de votre navigateur.
Comment fonctionnent les jetons CSRF dans Django
Lorsque vous lancez votre site avec le formulaire, Django crée automatiquement un cookie de navigateur appelé csrftoken. Ce cookie permet de suivre l’activité de l’utilisateur sur le site et d’identifier chaque utilisateur de manière unique.
Lorsque l’utilisateur soumet le formulaire, le serveur compare la valeur du cookie à la valeur de l’élément csrfmiddlewaretoken dans le champ de saisie caché. Si ces valeurs correspondent, le serveur traitera le formulaire avec succès, sinon il produira une erreur.
À première vue, les valeurs du cookie et de l’élément csrfmiddlewaretoken semblent être différents. Ceci est intentionnel et ajoute une couche de protection supplémentaire au jeton CSRF. Le jeton CSRF est comparé au cookie de la manière suivante :
- Le jeton get_token() masque le jeton CSRF avant de le transmettre au champ de saisie.
- Lorsque le formulaire est soumis, le jeton CSRF est démasqué à l’aide de la clé secrète du fichier de configuration.
- Le jeton démasqué est comparé au cookie de session.
- Si les valeurs sont identiques, le formulaire est traité. Dans le cas contraire, le serveur renvoie une erreur.
Pour empêcher les pirates de voler votre jeton CSRF, Django le renouvelle à chaque fois qu’il démarre une session utilisateur.
Création de jetons CSRF personnalisés
Bien que Django permette de protéger facilement vos formulaires en ajoutant simplement l’option {% csrf_token %}Il est également possible de générer des jetons CSRF et de les ajouter manuellement à vos formulaires. Pour ce faire, importez le fichier get_token() fonction :
from django.middleware.csrf import get_token
Dans votre vue, vous pouvez générer le jeton CSRF comme suit :
def view_name(request):
csrf_token = get_token(request)
# perform view logic
context = {
"csrf_token": csrf_token
}
return render(request, 'app_name/template.html', context=context)
Dans votre modèle HTML, vous pouvez inclure manuellement votre balise input et ajouter la balise csrf_token pour l’utiliser comme suit :
<form method="POST" >
<input type="hidden" name="csrfmiddlewaretoken" value="{{ csrf_token }}">
{{form.as_p}}
<button type="submit" class="btn btn-outline-secondary">Add Book</button>
</form>
Vous pouvez également générer le champ de saisie caché à partir de vos vues comme ceci :
def your_view(request):
csrf_token = get_token(request)
csrf_token_html = '<input type="hidden" name="csrfmiddlewaretoken" value="{}" />'.format(csrf_token)
# perform view logic
context = {
"csrf_token": csrf_token_html
}
return render(request, 'app_name/template.html', context=context)
Vous pouvez ensuite l’ajouter à votre modèle HTML comme ceci :
<form method="POST" >
{{ csrf_token_html|safe }}
{{form.as_p}}
<button type="submit" class="btn btn-outline-secondary">Add Book</button>
</form>
Si vous souhaitez contrôler complètement la protection CSRF de votre formulaire, vous pouvez le faire en comparant votre jeton CSRF au cookie stocké dans le navigateur. En fonction des résultats de la comparaison, vous pouvez traiter la soumission du formulaire comme vous le souhaitez. Voici un exemple :
from django.shortcuts import render
from django.middleware.csrf import get_token, _unmask_cipher_token
from django.utils.crypto import constant_time_compare
def your_view(request):
# Generate a custom CSRF token
csrf_token = get_token(request)
csrf_cookie = request.COOKIES.get('csrftoken')
# unmask csrf token
unmasked_csrf_token = _unmask_cipher_token(csrf_token)
# Compare the tokens
if not constant_time_compare(unmasked_csrf_token, csrf_cookie):
# Handle the case where the tokens don't match
pass
else:
# Handle the case where the tokens match
pass
# Render the template
context = {
'csrf_token': csrf_token,
}
return render(request, 'app_name/template.html', context=context)
Cet extrait de code récupère le csrf_cookie de l’objet de la requête HTTP. Il utilise ensuite l’élément _unmask_cipher_token() pour démasquer le csrf_token.
Une instruction conditionnelle compare les valeurs de l’élément csrf_cookie et le non masqué csrf_token. Cette comparaison utilise la méthode constant_time_compare pour se protéger contre les exploits temporels. Vous pouvez écrire votre logique en vous basant sur le résultat de la comparaison.
Désactivation de la protection CSRF dans Django
Même si Django prévoit par défaut une protection CSRF, vous pouvez la désactiver dans votre projet si vous le souhaitez. Il y a deux façons de le faire :
- Désactiver la protection CSRF sur l’ensemble de votre site web.
- Désactivation de la protection CSRF sur une vue spécifique.
Désactiver la protection CSRF sur l’ensemble de votre site web
Pour désactiver la protection CSRF de Django sur votre site web, vous devez simplement supprimer l’intergiciel CSRF de votre fichier de configuration. Dans votre fichier de configuration, localisez une liste appelée MIDDLEWARE. Dans la liste, recherchez ceci :
'django.middleware.csrf.CsrfViewMiddleware',
Une fois que vous l’avez trouvé, vous devez le supprimer de votre code pour désactiver la protection CSRF par défaut de Django.
Désactivation de la protection CSRF sur une vue spécifique
Si vous souhaitez désactiver la protection CSRF sur une vue spécifique de Django, utilisez l’option @csrf_exempt décorateur. Voici un extrait de code pour le démontrer :
from django.views.decorators.csrf import csrf_exempt
@csrf_exempt
def view_name(request):
# perform view logic
pass
Le décorateur @csrf_exempt n’est qu’un des nombreux décorateurs liés à la protection CSRF dans Django. Vous pouvez lire le reste sur la référence CSRF de Django.
Ne désactivez pas la protection CSRF sur votre site web
Bien que Django le permette, il n’est pas recommandé de désactiver le mécanisme de protection CSRF intégré à Django. Cela rendra votre site vulnérable aux attaques CSRF et affectera négativement les utilisateurs de votre application.
À moins que vous ne soyez un développeur expérimenté sachant comment mettre en œuvre un mécanisme de protection CSRF personnalisé, vous devriez travailler avec l’alternative fournie par Django.