Politique de sécurité de contenu (CSP)Lien vers cette rubrique

La politique de sécurité de contenu (CSP) est un standard de sécurité web aidant à prévenir les attaques par injection de contenu en limitant les sources à partir desquelles le contenu peut être chargé. Elle joue un rôle important dans le cadre d’une stratégie de sécurité complète.

Pour des instructions de configuration dans un projet Django, consultez la documentation Utilisation de CSP. Pour un guide HTTP au sujet de CSP, consultez le guide MDN sur CSP.

AperçuLien vers cette rubrique

La spécification Content-Security-Policy définit deux en-têtes complémentaires :

  • Content-Security-Policy: applique la politique CSP, en bloquant le contenu qui viole les directives définies.

  • Content-Security-Policy-Report-Only: signale les violations CSP sans bloquer le contenu, permettant de tester sans dommage.

Chaque politique est composée d’une ou de plusieurs directives avec leurs valeurs, qui indiquent ensemble au navigateur la façon de gérer des types spécifiques de contenus.

Lorsque ContentSecurityPolicyMiddleware est activé, Django construit et lie automatiquement les en-têtes appropriés à chaque réponse en fonction des réglages configurés, sauf s’ils ont déjà été définis par une autre couche.

RéglagesLien vers cette rubrique

ContentSecurityPolicyMiddleware est configuré en utilisant les réglages suivants:

  • SECURE_CSP: définit la politique de sécurité de contenu comme appliquée.

  • SECURE_CSP_REPORT_ONLY: définit la politique de sécurité de contenu en mode signalement uniquement.

Rapports de violation de politiqueLien vers cette rubrique

Lorsqu’une violation CSP se produit, les navigateurs journalisent typiquement les détails dans la console de développement, fournissant un retour immédiat durant le développement. Pour recevoir aussi ces rapports de façon programmatique, la politique doit inclure une directive de signalement telle que report-uri qui indique où les données de violation doivent être envoyées.

Django prend en charge la configuration de ces directives via le réglage SECURE_CSP_REPORT_ONLY, mais les signalements ne vont être déclenchés par le navigateur que si la politique inclut explicitement une directive de signalement valable.

Django ne fournit pas de fonctionnalité intégrée pour recevoir, stocker ou traiter les rapports de violation. Pour les collecter et les analyser, vous devez implémenter vos propres points d’accès de signalement, ou intégrer un service de surveillance de tierce partie.

Constantes CSPLien vers cette rubrique

Django fournit des constantes prédéfinies représentant des mots-clés d’expressions sources CSP courants, tels que 'self', 'none' et 'unsafe-inline'. Ces constantes sont prévues pour être utilisées dans les valeurs de directives définies dans les réglages.

Elles sont disponibles par l’énumération CSP, et il est recommandé de les utiliser plutôt que les chaînes brutes. Cela aide à éviter les erreurs courantes telles que des fautes d’orthographe, des mises sous guillemets incorrectes ou de la mise en forme incohérente, et permet de garantir le respect de la spécification CSP.

class CSPLien vers cette définition

Énumération fournissant des constantes standardisées pour les expressions sources CSP courantes.

NONELien vers cette définition

Représente 'none'. Bloque le chargement de ressources pour la directive donnée.

REPORT_SAMPLELien vers cette définition

Représente 'report-sample'. Indique au navigateur d’inclure un extrait du code en faute dans les rapports. Sachez que cela pourrait exposer des données sensibles.

SELFLien vers cette définition

Représente 'self'. Autorise à charger des ressources à partir de la même origine (même protocole, hôte et port).

STRICT_DYNAMICLien vers cette définition

Représente 'strict-dynamic'. Autorise l’exécution de scripts chargés par un script de confiance (par ex. un script possédant un nonce ou une empreinte valide), sans avoir besoin de 'unsafe-inline'.

UNSAFE_EVALLien vers cette définition

Représente 'unsafe-eval'. Autorise l’utilisation d”eval() et des fonctions JavaScript similaires. Fortement découragé.

UNSAFE_HASHESLien vers cette définition

Représente 'unsafe-hashes'. Autorise les gestionnaires d’événements et certains URI javascript: lorsque l’empreinte de leur contenu correspond à une règle de la politique. Nécessite le niveau 3+ de CSP.

UNSAFE_INLINELien vers cette définition

Représente 'unsafe-inline'. Autorise l’exécution de scripts, styles et URL javascript: intégrés dans les pages. Généralement déconseillé, particulièrement pour les scripts.

WASM_UNSAFE_EVALLien vers cette définition

Représente 'wasm-unsafe-eval'. Permet la compilation et l’exécution de code WebAssembly sans activer 'unsafe-eval' pour les scripts.

NONCELien vers cette définition

La valeur de substitution spécifique à Django ("<CSP_NONCE_SENTINEL>") utilisée dans les directives script-src ou style-src pour activer le CSP basé sur les nonces. Au moment de son exécution, l’intergiciel ContentSecurityPolicyMiddleware remplace cette chaîne par un nonce sécurisé et aléatoire généré pour chaque requête. Voir les explications détaillées dans Utilisation des nonces.

DécorateursLien vers cette rubrique

Django fournit des décorateurs pour contrôler les en-têtes CSP pour chaque vue. Cela permet de surcharger ou désactiver la politique d’application ou de signalement seul pour des vues particulières, fournissant un contrôle fin lorsque les réglages globaux ne suffisent pas. L’application de ces surcharges remplace complètement le CSP de base : il n’y a pas de fusion avec les règles existantes. Elles peuvent être utilisées conjointement avec les constantes définies dans CSP.

csp_override(config)(view)Lien vers cette définition

Surcharge l’en-tête Content-Security-Policy pour la vue décorée en utilisant des directives au même format que le réglage SECURE_CSP.

L’argument config doit être une correspondance entre les directives CSP souhaitées. Si config est vide ({}), aucun en-tête CSP ne sera appliqué à la réponse renvoyée par cette vue, ce qui désactivera en pratique CSP pour cette vue.

Exemples :

Code
from django.http import HttpResponse
from django.utils.csp import CSP
from django.views.decorators.csp import csp_override


@csp_override(
    {
        "default-src": [CSP.SELF],
        "img-src": [CSP.SELF, "data:"],
    }
)
def my_view(request):
    return HttpResponse("Custom Content-Security-Policy header applied")


@csp_override({})
def my_other_view(request):
    return HttpResponse("No Content-Security-Policy header added")
csp_report_only_override(config)(view)Lien vers cette définition

Surcharge l’en-tête Content-Security-Policy-Report-Only pour la vue décorée en utilisant des directives au même format que le réglage SECURE_CSP_REPORT_ONLY.

Comme pour csp_override(), l’argument config doit être une correspondance entre les directives CSP souhaitées. Si config est vide ({}), aucun en-tête CSP en mode signalement ne sera appliqué à la réponse renvoyée par cette vue, ce qui désactivera en pratique CSP en mode signalement pour cette vue.

Exemples :

Code
from django.http import HttpResponse
from django.utils.csp import CSP
from django.views.decorators.csp import csp_report_only_override


@csp_report_only_override(
    {
        "default-src": [CSP.SELF],
        "img-src": [CSP.SELF, "data:"],
        "report-uri": "https://mysite.com/csp-report/",
    }
)
def my_view(request):
    return HttpResponse("Custom Content-Security-Policy-Report-Only header applied")


@csp_report_only_override({})
def my_other_view(request):
    return HttpResponse("No Content-Security-Policy-Report-Only header added")

Les exemples ci-dessus s’appliquent à des vues basées sur des fonctions. Pour les vues fondées sur les classes, consultez le guide de décoration des vues fondées sur les classes.

Utilisation des noncesLien vers cette rubrique

Un nonce CSP (« nombre utilisé une seule fois ») est une valeur unique et aléatoire générée pour chaque réponse HTTP. Django prend en charge les nonces comme manière sécurisée d’autoriser des balises <script> ou <style> intégrées dans les pages à s’exécuter sans devoir définir 'unsafe-inline'.

Les nonces sont activés en incluant le substituant spécial NONCE dans les directives concernées de vos réglages CSP, tels que script-src ou style-src. Lorsqu’il est actif, l’intergiciel ContentSecurityPolicyMiddleware va générer un nonce et insérer l’expression source nonce-<valeur> correspondante dans l’en-tête CSP.

To use this nonce in templates, the csp() context processor needs to be enabled. It adds a csp_nonce variable to the template context.

For inline <script> and <style> elements, include the nonce directly using the context variable:

Django template
<script nonce="{{ csp_nonce }}">
  // This inline JavaScript will be allowed.
</script>

Pour les éléments <script src="..."> et <link rel="stylesheet"> externes, utilisez la balise de gabarit csp_nonce_attr:

Django template
<script src="/path/to/script.js" {% csp_nonce_attr %}></script>
<link rel="stylesheet" href="/path/to/style.css" {% csp_nonce_attr %}>

To render a Media object’s assets with the nonce applied, pass the object to the csp_nonce_attr template tag:

Django template
{% csp_nonce_attr form.media %}

Le navigateur ne va exécuter les éléments inclus dans les pages que s’ils contiennent un attribut nonce=<valeur> correspondant à celui qui est présent dans l’en-tête Content-Security-Policy (ou Content-Security-Policy-Report-Only). Ce mécanisme fournit un contrôle granulaire fin sur quelle partie de code intégré est autorisée à s’exécuter.

If a template includes the CSP nonce but the policy does not include NONCE, the HTML will include a nonce attribute, but the header will lack the required source expression. In this case, the browser will block the inline script or style (or report it for report-only configurations).

Génération et mise en cache des noncesLien vers cette rubrique

La génération des nonces de Django est différée : l’intergiciel ne génère un nonce que si {{ csp_nonce }} est accédé durant le rendu du gabarit. Cela évite du travail inutile pour les pages qui n’utilisent pas de nonce.

Cependant, comme les nonces doivent être uniques pour chaque requête, un soin particulier doit être apporté lors de l’utilisation des caches de pages complètes (par ex. l’intergiciel de cache de Django ou le cache des CDN). Servir des réponses à partir du cache avec des nonces générés précédemment peut aboutir à des réutilisations pour différentes personnes et requêtes. Même si de telles réponses peuvent sembler fonctionner (car le nonce de l’en-tête CSP correspond au contenu HTML), cette réutilisation casse l’objectif attendu et affaiblit la sécurité.

Pour s’assurer que les politiques basées sur des nonces restent efficaces :

  • Avoid caching full responses that include {{ csp_nonce }} or csp_nonce_attr.

  • Si le cache est indispensable, utilisez une stratégie qui injecte un nonce tout frais dans chaque requête, ou envisagez une refonte de votre application afin d’éviter totalement l’insertion de scripts et styles en ligne.