Django
Sécurité
Recherche…
Protection XSS (Cross Site Scripting)
Les attaques XSS consistent à injecter du code HTML (ou JS) dans une page. Voir Qu'est-ce qu'un script intersite pour plus d'informations.
Pour éviter cette attaque, par défaut, Django échappe aux chaînes passées par une variable de modèle.
Compte tenu du contexte suivant:
context = {
'class_name': 'large" style="font-size:4000px',
'paragraph': (
"<script type=\"text/javascript\">alert('hello world!');</script>"),
}
<p class="{{ class_name }}">{{ paragraph }}</p>
<!-- Will be rendered as: -->
<p class="large" style="font-size: 4000px"><script>alert('hello world!');</script></p>
Si vous avez des variables contenant du code HTML que vous avez confiance et que vous voulez réellement rendre, vous devez explicitement le déclarer sûr:
<p class="{{ class_name|safe }}">{{ paragraph }}</p>
<!-- Will be rendered as: -->
<p class="large" style="font-size: 4000px"><script>alert('hello world!');</script></p>
Si vous avez un bloc contenant plusieurs variables qui sont toutes sûres, vous pouvez désactiver localement l'échappement automatique:
{% autoescape off %}
<p class="{{ class_name }}">{{ paragraph }}</p>
{% endautoescape %}
<!-- Will be rendered as: -->
<p class="large" style="font-size: 4000px"><script>alert('hello world!');</script></p>
Vous pouvez également marquer une chaîne comme sûre en dehors du modèle:
from django.utils.safestring import mark_safe
context = {
'class_name': 'large" style="font-size:4000px',
'paragraph': mark_safe(
"<script type=\"text/javascript\">alert('hello world!');</script>"),
}
<p class="{{ class_name }}">{{ paragraph }}</p>
<!-- Will be rendered as: -->
<p class="large" style="font-size: 4000px"><script>alert('hello world!');</script></p>
Certains utilitaires Django tels que format_html
déjà des chaînes marquées comme sûres:
from django.utils.html import format_html
context = {
'var': format_html('<b>{}</b> {}', 'hello', '<i>world!</i>'),
}
<p>{{ var }}</p>
<!-- Will be rendered as -->
<p><b>hello</b> <i>world!</i></p>
Protection de clickjacking
Clickjacking est une technique malveillante qui consiste à inciter un utilisateur Web à cliquer sur quelque chose de différent de ce que l’utilisateur perçoit en cliquant dessus. Apprendre encore plus
Pour activer la protection contre le XFrameOptionsMiddleware
de XFrameOptionsMiddleware
, ajoutez le XFrameOptionsMiddleware
à vos classes de middleware. Cela devrait déjà être là si vous ne l'avez pas supprimé.
# settings.py
MIDDLEWARE_CLASSES = [
...
'django.middleware.clickjacking.XFrameOptionsMiddleware',
...
]
Ce middleware définit l'en-tête 'X-Frame-Options' sur toutes vos réponses, à moins d'une exemption explicite ou déjà définie (non remplacée si elle est déjà définie dans la réponse). Par défaut, il est défini sur "SAMEORIGIN". Pour changer cela, utilisez le paramètre X_FRAME_OPTIONS
:
X_FRAME_OPTIONS = 'DENY'
Vous pouvez remplacer le comportement par défaut pour chaque vue.
from django.utils.decorators import method_decorator
from django.views.decorators.clickjacking import (
xframe_options_exempt, xframe_options_deny, xframe_options_sameorigin,
)
xframe_options_exempt_m = method_decorator(xframe_options_exempt, name='dispatch')
@xframe_options_sameorigin
def my_view(request, *args, **kwargs):
"""Forces 'X-Frame-Options: SAMEORIGIN'."""
return HttpResponse(...)
@method_decorator(xframe_options_deny, name='dispatch')
class MyView(View):
"""Forces 'X-Frame-Options: DENY'."""
@xframe_options_exempt_m
class MyView(View):
"""Does not set 'X-Frame-Options' header when passing through the
XFrameOptionsMiddleware.
"""
Protection contre la falsification de sites inter-sites (CSRF)
La falsification de requêtes intersites, également connue sous le nom d'attaque en un clic ou d'équitation de session et abrégée CSRF ou XSRF, est un type d'exploitation malveillante d'un site Web sur lequel des commandes non autorisées sont transmises par un utilisateur du site. Apprendre encore plus
Pour activer la protection CSRF, ajoutez le CsrfViewMiddleware
à vos classes de middleware. Ce middleware est activé par défaut.
# settings.py
MIDDLEWARE_CLASSES = [
...
'django.middleware.csrf.CsrfViewMiddleware',
...
]
Ce middleware définira un jeton dans un cookie sur la réponse sortante. Chaque fois qu'une requête entrante utilise une méthode non sécurisée (n'importe quelle méthode sauf GET
, HEAD
, OPTIONS
et TRACE
), le cookie doit correspondre à un jeton envoyé en tant que données de formulaire csrfmiddlewaretoken
ou en X-CsrfToken
tête X-CsrfToken
. Cela garantit que le client à l'origine de la demande est également le propriétaire du cookie et, par extension, la session (authentifiée).
Si une demande est faite via HTTPS
, la vérification stricte du référent est activée. Si l'en HTTP_REFERER
tête HTTP_REFERER
ne correspond pas à l'hôte de la demande en cours ou à un hôte dans CSRF_TRUSTED_ORIGINS
( nouveau dans 1.9 ), la demande est refusée.
Les formulaires qui utilisent la méthode POST
doivent inclure le jeton CSRF dans le modèle. La balise de modèle {% csrf_token %}
affichera un champ masqué et garantira que le cookie est défini sur la réponse:
<form method='POST'>
{% csrf_token %}
...
</form>
Les vues individuelles qui ne sont pas vulnérables aux attaques CSRF peuvent être exemptées à l'aide du décorateur @csrf_exempt
:
from django.views.decorators.csrf import csrf_exempt
@csrf_exempt
def my_view(request, *args, **kwargs):
"""Allows unsafe methods without CSRF protection"""
return HttpResponse(...)
Bien que cela ne soit pas recommandé, vous pouvez désactiver le CsrfViewMiddleware
si beaucoup de vos vues ne sont pas vulnérables aux attaques CSRF. Dans ce cas, vous pouvez utiliser le décorateur @csrf_protect
pour protéger les vues individuelles:
from django.views.decorators.csrf import csrf_protect
@csrf_protect
def my_view(request, *args, **kwargs):
"""This view is protected against CSRF attacks if the middleware is disabled"""
return HttpResponse(...)