{"title":"Protection contre le « Cross site request forgery » (CSRF)","version":"1.9","locale":"fr","docname":"ref/csrf","url":"/fr/1.9/ref/csrf/","canonical":"https://djangodocs.dev/fr/1.9/ref/csrf/","summary":"L’intergiciel et les balises de gabarit CSRF permettent de se protéger facilement contre les attaques de type Cross Site Request Forgeries . Ce type d’attaque se…","html":"<span id=\"cross-site-request-forgery-protection\"></span><h1>Protection contre le « Cross site request forgery » (CSRF)<a class=\"heading-anchor\" href=\"#module-django.middleware.csrf\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h1>\n<p>L’intergiciel et les balises de gabarit CSRF permettent de se protéger facilement contre les attaques de type  <a class=\"reference external\" href=\"https://www.squarefree.com/securitytips/web-developers.html#CSRF\">Cross Site Request Forgeries</a>. Ce type d’attaque se produit quand un site Web malveillant contient un lien, un bouton de formulaire ou un peu de JavaScript qui est destiné à effectuer une action sur votre site Web, en utilisant les informations d’identification d’un utilisateur connecté qui visite le site malveillant dans son navigateur. Un type d’attaque liée est également couverte : celle du « login CSRF », où un site attaquant piège le navigateur d’un utilisateur en se connectant à un site avec les informations d’identification de quelqu’un d’autre.</p>\n<p>The first defense against CSRF attacks is to ensure that GET requests (and other\n“safe” methods, as defined by <span class=\"target\" id=\"index-0\"></span><a class=\"rfc reference external\" href=\"https://datatracker.ietf.org/doc/html/rfc7231.html#section-4.2.1\"><strong>RFC 7231 Section 4.2.1</strong></a>) are side effect free.\nRequests via “unsafe” methods, such as POST, PUT, and DELETE, can then be\nprotected by following the steps below.</p>\n<section id=\"how-to-use-it\">\n<span id=\"using-csrf\"></span><h2>Comment l’utiliser<a class=\"heading-anchor\" href=\"#how-to-use-it\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>Pour profiter de la protection CSRF dans les vues, procédez comme suit :</p>\n<ol class=\"arabic\">\n<li><p>L’intergiciel CSRF est activé par défaut dans le réglage <a class=\"reference internal\" href=\"/fr/1.9/ref/settings/#std-setting-MIDDLEWARE_CLASSES\"><code class=\"xref std std-setting docutils literal notranslate\"><span class=\"pre\">MIDDLEWARE_CLASSES</span></code></a>. Si vous surchargez ce réglage, rappelez-vous que <code class=\"docutils literal notranslate\"><span class=\"pre\">'django.middleware.csrf.CsrfViewMiddleware'</span></code> doit figurer avant les intergiciels qui comptent sur le fait que les attaques CSRF ont déjà été contrées.</p>\n<p>Si vous le désactivez, ce qui n’est pas recommandé, vous pouvez utiliser <a class=\"reference internal\" href=\"#django.views.decorators.csrf.csrf_protect\" title=\"django.views.decorators.csrf.csrf_protect\"><code class=\"xref py py-func docutils literal notranslate\"><span class=\"pre\">csrf_protect()</span></code></a> sur certaines vues que vous souhaitez protéger (voir ci-dessous).</p>\n</li>\n<li><p>In any template that uses a POST form, use the <a class=\"reference internal\" href=\"/fr/1.9/ref/templates/builtins/#std-templatetag-csrf_token\"><code class=\"xref std std-ttag docutils literal notranslate\"><span class=\"pre\">csrf_token</span></code></a> tag inside\nthe <code class=\"docutils literal notranslate\"><span class=\"pre\">&lt;form&gt;</span></code> element if the form is for an internal URL, e.g.:</p>\n<div class=\"code-block\" data-language=\"html+django\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Django template</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Django template code\"><code><span class=\"p\">&lt;</span><span class=\"nt\">form</span> <span class=\"na\">action</span><span class=\"o\">=</span><span class=\"s\">&quot;&quot;</span> <span class=\"na\">method</span><span class=\"o\">=</span><span class=\"s\">&quot;post&quot;</span><span class=\"p\">&gt;</span><span class=\"cp\">{%</span> <span class=\"k\">csrf_token</span> <span class=\"cp\">%}</span>\n</code></pre></div>\n<p>Par contre, il ne faut pas le faire pour les formulaires POST qui ciblent des URL externes, car cela entraînerait la divulgation du jeton CSRF, et conduirait ainsi à une vulnérabilité.</p>\n</li>\n<li><p>Dans les fonctions de vue correspondantes, vérifiez que <a class=\"reference internal\" href=\"/fr/1.9/ref/templates/api/#django.template.RequestContext\" title=\"django.template.RequestContext\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">RequestContext</span></code></a> est utilisé pour produire la réponse afin que <code class=\"docutils literal notranslate\"><span class=\"pre\">{%</span> <span class=\"pre\">csrf_token</span> <span class=\"pre\">%}</span></code> fonctionne correctement. Si vous utilisez la fonction <a class=\"reference internal\" href=\"/fr/1.9/topics/http/shortcuts/#django.shortcuts.render\" title=\"django.shortcuts.render\"><code class=\"xref py py-func docutils literal notranslate\"><span class=\"pre\">render()</span></code></a>, les vues génériques ou les applications contribuées, il n’y a pas de soucis à se faire car toutes ces vues utilisent <code class=\"docutils literal notranslate\"><span class=\"pre\">RequestContext</span></code>.</p></li>\n</ol>\n<section id=\"ajax\">\n<span id=\"csrf-ajax\"></span><h3>AJAX<a class=\"heading-anchor\" href=\"#ajax\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>Même si la méthode ci-dessus peut être utilisée pour les requêtes AJAX POST, elle présente quelques inconvénients : il ne faut pas oublier de passer le jeton CSRF en même temps que les données POST à ​​chaque requête POST. Pour cette raison, il y a une autre méthode : sur chaque XMLHttpRequest, définissez un élément d’en-tête <code class=\"docutils literal notranslate\"><span class=\"pre\">X-CSRFToken</span></code> ayant la même valeur que le jeton CSRF. C’est souvent plus simple, parce que de nombreuses bibliothèques JavaScript fournissent des points d’extension qui permettent d’ajouter des éléments d’en-tête pour chaque requête.</p>\n<p>En premier lieu, vous devez obtenir le jeton CSRF lui-même. La source recommandée pour le jeton est le cookie <code class=\"docutils literal notranslate\"><span class=\"pre\">csrftoken</span></code>, qui sera présent si vous avez activé la protection CSRF pour votre vue, comme indiqué ci-dessus.</p>\n<aside class=\"admonition admonition-note\" role=\"note\">\n<p class=\"admonition-title\">Note</p>\n<p>Le cookie CSRF est nommé <code class=\"docutils literal notranslate\"><span class=\"pre\">csrftoken</span></code> par défaut, mais vous pouvez modifier ce nom via le réglage <a class=\"reference internal\" href=\"/fr/1.9/ref/settings/#std-setting-CSRF_COOKIE_NAME\"><code class=\"xref std std-setting docutils literal notranslate\"><span class=\"pre\">CSRF_COOKIE_NAME</span></code></a>.</p>\n<p>Le nom d’en-tête CSRF est <code class=\"docutils literal notranslate\"><span class=\"pre\">HTTP_X_CSRFTOKEN</span></code> par défaut, mais vous pouvez modifier ce nom via le réglage <a class=\"reference internal\" href=\"/fr/1.9/ref/settings/#std-setting-CSRF_HEADER_NAME\"><code class=\"xref std std-setting docutils literal notranslate\"><span class=\"pre\">CSRF_HEADER_NAME</span></code></a>.</p>\n</aside>\n<p>L’acquisition du jeton est simple :</p>\n<div class=\"code-block\" data-language=\"javascript\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">JavaScript</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"JavaScript code\"><code><span class=\"c1\">// using jQuery</span>\n<span class=\"kd\">function</span><span class=\"w\"> </span><span class=\"nx\">getCookie</span><span class=\"p\">(</span><span class=\"nx\">name</span><span class=\"p\">)</span><span class=\"w\"> </span><span class=\"p\">{</span>\n<span class=\"w\">    </span><span class=\"kd\">var</span><span class=\"w\"> </span><span class=\"nx\">cookieValue</span><span class=\"w\"> </span><span class=\"o\">=</span><span class=\"w\"> </span><span class=\"kc\">null</span><span class=\"p\">;</span>\n<span class=\"w\">    </span><span class=\"k\">if</span><span class=\"w\"> </span><span class=\"p\">(</span><span class=\"nb\">document</span><span class=\"p\">.</span><span class=\"nx\">cookie</span><span class=\"w\"> </span><span class=\"o\">&amp;&amp;</span><span class=\"w\"> </span><span class=\"nb\">document</span><span class=\"p\">.</span><span class=\"nx\">cookie</span><span class=\"w\"> </span><span class=\"o\">!==</span><span class=\"w\"> </span><span class=\"s1\">&#39;&#39;</span><span class=\"p\">)</span><span class=\"w\"> </span><span class=\"p\">{</span>\n<span class=\"w\">        </span><span class=\"kd\">var</span><span class=\"w\"> </span><span class=\"nx\">cookies</span><span class=\"w\"> </span><span class=\"o\">=</span><span class=\"w\"> </span><span class=\"nb\">document</span><span class=\"p\">.</span><span class=\"nx\">cookie</span><span class=\"p\">.</span><span class=\"nx\">split</span><span class=\"p\">(</span><span class=\"s1\">&#39;;&#39;</span><span class=\"p\">);</span>\n<span class=\"w\">        </span><span class=\"k\">for</span><span class=\"w\"> </span><span class=\"p\">(</span><span class=\"kd\">var</span><span class=\"w\"> </span><span class=\"nx\">i</span><span class=\"w\"> </span><span class=\"o\">=</span><span class=\"w\"> </span><span class=\"mf\">0</span><span class=\"p\">;</span><span class=\"w\"> </span><span class=\"nx\">i</span><span class=\"w\"> </span><span class=\"o\">&lt;</span><span class=\"w\"> </span><span class=\"nx\">cookies</span><span class=\"p\">.</span><span class=\"nx\">length</span><span class=\"p\">;</span><span class=\"w\"> </span><span class=\"nx\">i</span><span class=\"o\">++</span><span class=\"p\">)</span><span class=\"w\"> </span><span class=\"p\">{</span>\n<span class=\"w\">            </span><span class=\"kd\">var</span><span class=\"w\"> </span><span class=\"nx\">cookie</span><span class=\"w\"> </span><span class=\"o\">=</span><span class=\"w\"> </span><span class=\"nx\">jQuery</span><span class=\"p\">.</span><span class=\"nx\">trim</span><span class=\"p\">(</span><span class=\"nx\">cookies</span><span class=\"p\">[</span><span class=\"nx\">i</span><span class=\"p\">]);</span>\n<span class=\"w\">            </span><span class=\"c1\">// Does this cookie string begin with the name we want?</span>\n<span class=\"w\">            </span><span class=\"k\">if</span><span class=\"w\"> </span><span class=\"p\">(</span><span class=\"nx\">cookie</span><span class=\"p\">.</span><span class=\"nx\">substring</span><span class=\"p\">(</span><span class=\"mf\">0</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"nx\">name</span><span class=\"p\">.</span><span class=\"nx\">length</span><span class=\"w\"> </span><span class=\"o\">+</span><span class=\"w\"> </span><span class=\"mf\">1</span><span class=\"p\">)</span><span class=\"w\"> </span><span class=\"o\">===</span><span class=\"w\"> </span><span class=\"p\">(</span><span class=\"nx\">name</span><span class=\"w\"> </span><span class=\"o\">+</span><span class=\"w\"> </span><span class=\"s1\">&#39;=&#39;</span><span class=\"p\">))</span><span class=\"w\"> </span><span class=\"p\">{</span>\n<span class=\"w\">                </span><span class=\"nx\">cookieValue</span><span class=\"w\"> </span><span class=\"o\">=</span><span class=\"w\"> </span><span class=\"nb\">decodeURIComponent</span><span class=\"p\">(</span><span class=\"nx\">cookie</span><span class=\"p\">.</span><span class=\"nx\">substring</span><span class=\"p\">(</span><span class=\"nx\">name</span><span class=\"p\">.</span><span class=\"nx\">length</span><span class=\"w\"> </span><span class=\"o\">+</span><span class=\"w\"> </span><span class=\"mf\">1</span><span class=\"p\">));</span>\n<span class=\"w\">                </span><span class=\"k\">break</span><span class=\"p\">;</span>\n<span class=\"w\">            </span><span class=\"p\">}</span>\n<span class=\"w\">        </span><span class=\"p\">}</span>\n<span class=\"w\">    </span><span class=\"p\">}</span>\n<span class=\"w\">    </span><span class=\"k\">return</span><span class=\"w\"> </span><span class=\"nx\">cookieValue</span><span class=\"p\">;</span>\n<span class=\"p\">}</span>\n<span class=\"kd\">var</span><span class=\"w\"> </span><span class=\"nx\">csrftoken</span><span class=\"w\"> </span><span class=\"o\">=</span><span class=\"w\"> </span><span class=\"nx\">getCookie</span><span class=\"p\">(</span><span class=\"s1\">&#39;csrftoken&#39;</span><span class=\"p\">);</span>\n</code></pre></div>\n<p>Le code ci-dessus pourrait être simplifié en utilisant la <a class=\"reference external\" href=\"https://github.com/js-cookie/js-cookie/\">bibliothèque JavaScript Cookie</a> pour remplacer <code class=\"docutils literal notranslate\"><span class=\"pre\">getCookie</span></code>:</p>\n<div class=\"code-block\" data-language=\"javascript\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">JavaScript</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"JavaScript code\"><code><span class=\"kd\">var</span><span class=\"w\"> </span><span class=\"nx\">csrftoken</span><span class=\"w\"> </span><span class=\"o\">=</span><span class=\"w\"> </span><span class=\"nx\">Cookies</span><span class=\"p\">.</span><span class=\"nx\">get</span><span class=\"p\">(</span><span class=\"s1\">&#39;csrftoken&#39;</span><span class=\"p\">);</span>\n</code></pre></div>\n<aside class=\"admonition admonition-note\" role=\"note\">\n<p class=\"admonition-title\">Note</p>\n<p>Le jeton CSRF est également présent dans le DOM, mais seulement s’il est explicitement inclus à l’aide de la balise <a class=\"reference internal\" href=\"/fr/1.9/ref/templates/builtins/#std-templatetag-csrf_token\"><code class=\"xref std std-ttag docutils literal notranslate\"><span class=\"pre\">csrf_token</span></code></a> dans un gabarit. Le cookie contiendra le jeton standard ; le <code class=\"docutils literal notranslate\"><span class=\"pre\">CsrfViewMiddleware</span></code> préfèrera le cookie au jeton du DOM. De toute façon, vous êtes assuré d’avoir le cookie si le jeton est présent dans le DOM, il est donc préférable d’utiliser le cookie !</p>\n</aside>\n<aside class=\"admonition admonition-warning\" role=\"note\">\n<p class=\"admonition-title\">Avertissement</p>\n<p>Si la vue n’utilise pas un gabarit contenant la balise <a class=\"reference internal\" href=\"/fr/1.9/ref/templates/builtins/#std-templatetag-csrf_token\"><code class=\"xref std std-ttag docutils literal notranslate\"><span class=\"pre\">csrf_token</span></code></a>, Django peut ne pas définir le cookie CSRF. Cette situation apparaît souvent dans les cas où les formulaires sont ajoutés dynamiquement à la page. Pour résoudre ce problème, Django fournit un décorateur de vue qui force l’utilisation du cookie : <a class=\"reference internal\" href=\"#django.views.decorators.csrf.ensure_csrf_cookie\" title=\"django.views.decorators.csrf.ensure_csrf_cookie\"><code class=\"xref py py-func docutils literal notranslate\"><span class=\"pre\">ensure_csrf_cookie()</span></code></a>.</p>\n</aside>\n<p>Pour terminer, il reste à effectivement définir l’en-tête sur la requête AJAX, tout en évitant que le jeton CSRF soit envoyé à d’autres domaines en utilisant <a class=\"reference external\" href=\"https://api.jquery.com/jQuery.ajax\">settings.crossDomain</a> dans les versions de jQuery 1.5.1 ou plus récentes :</p>\n<div class=\"code-block\" data-language=\"javascript\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">JavaScript</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"JavaScript code\"><code><span class=\"kd\">function</span><span class=\"w\"> </span><span class=\"nx\">csrfSafeMethod</span><span class=\"p\">(</span><span class=\"nx\">method</span><span class=\"p\">)</span><span class=\"w\"> </span><span class=\"p\">{</span>\n<span class=\"w\">    </span><span class=\"c1\">// these HTTP methods do not require CSRF protection</span>\n<span class=\"w\">    </span><span class=\"k\">return</span><span class=\"w\"> </span><span class=\"p\">(</span><span class=\"sr\">/^(GET|HEAD|OPTIONS|TRACE)$/</span><span class=\"p\">.</span><span class=\"nx\">test</span><span class=\"p\">(</span><span class=\"nx\">method</span><span class=\"p\">));</span>\n<span class=\"p\">}</span>\n<span class=\"nx\">$</span><span class=\"p\">.</span><span class=\"nx\">ajaxSetup</span><span class=\"p\">({</span>\n<span class=\"w\">    </span><span class=\"nx\">beforeSend</span><span class=\"o\">:</span><span class=\"w\"> </span><span class=\"kd\">function</span><span class=\"p\">(</span><span class=\"nx\">xhr</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"nx\">settings</span><span class=\"p\">)</span><span class=\"w\"> </span><span class=\"p\">{</span>\n<span class=\"w\">        </span><span class=\"k\">if</span><span class=\"w\"> </span><span class=\"p\">(</span><span class=\"o\">!</span><span class=\"nx\">csrfSafeMethod</span><span class=\"p\">(</span><span class=\"nx\">settings</span><span class=\"p\">.</span><span class=\"nx\">type</span><span class=\"p\">)</span><span class=\"w\"> </span><span class=\"o\">&amp;&amp;</span><span class=\"w\"> </span><span class=\"o\">!</span><span class=\"k\">this</span><span class=\"p\">.</span><span class=\"nx\">crossDomain</span><span class=\"p\">)</span><span class=\"w\"> </span><span class=\"p\">{</span>\n<span class=\"w\">            </span><span class=\"nx\">xhr</span><span class=\"p\">.</span><span class=\"nx\">setRequestHeader</span><span class=\"p\">(</span><span class=\"s2\">&quot;X-CSRFToken&quot;</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"nx\">csrftoken</span><span class=\"p\">);</span>\n<span class=\"w\">        </span><span class=\"p\">}</span>\n<span class=\"w\">    </span><span class=\"p\">}</span>\n<span class=\"p\">});</span>\n</code></pre></div>\n<p>Si vous utilisez AngularJS 1.1.3 ou plus récente, il suffit de configurer le fournisseur <code class=\"docutils literal notranslate\"><span class=\"pre\">$http</span></code> avec les noms de cookie et d’en-tête :</p>\n<div class=\"code-block\" data-language=\"javascript\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">JavaScript</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"JavaScript code\"><code><span class=\"nx\">$httpProvider</span><span class=\"p\">.</span><span class=\"nx\">defaults</span><span class=\"p\">.</span><span class=\"nx\">xsrfCookieName</span><span class=\"w\"> </span><span class=\"o\">=</span><span class=\"w\"> </span><span class=\"s1\">&#39;csrftoken&#39;</span><span class=\"p\">;</span>\n<span class=\"nx\">$httpProvider</span><span class=\"p\">.</span><span class=\"nx\">defaults</span><span class=\"p\">.</span><span class=\"nx\">xsrfHeaderName</span><span class=\"w\"> </span><span class=\"o\">=</span><span class=\"w\"> </span><span class=\"s1\">&#39;X-CSRFToken&#39;</span><span class=\"p\">;</span>\n</code></pre></div>\n</section>\n<section id=\"using-csrf-in-jinja2-templates\">\n<h3>Using CSRF in Jinja2 templates<a class=\"heading-anchor\" href=\"#using-csrf-in-jinja2-templates\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>Django’s <a class=\"reference internal\" href=\"/fr/1.9/topics/templates/#django.template.backends.jinja2.Jinja2\" title=\"django.template.backends.jinja2.Jinja2\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">Jinja2</span></code></a> template backend\nadds <code class=\"docutils literal notranslate\"><span class=\"pre\">{{</span> <span class=\"pre\">csrf_input</span> <span class=\"pre\">}}</span></code> to the context of all templates which is equivalent\nto <code class=\"docutils literal notranslate\"><span class=\"pre\">{%</span> <span class=\"pre\">csrf_token</span> <span class=\"pre\">%}</span></code> in the Django template language. For example:</p>\n<div class=\"code-block\" data-language=\"html+jinja\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Html Jinja</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Html Jinja code\"><code><span class=\"p\">&lt;</span><span class=\"nt\">form</span> <span class=\"na\">action</span><span class=\"o\">=</span><span class=\"s\">&quot;&quot;</span> <span class=\"na\">method</span><span class=\"o\">=</span><span class=\"s\">&quot;post&quot;</span><span class=\"p\">&gt;</span><span class=\"cp\">{{</span> <span class=\"nv\">csrf_input</span> <span class=\"cp\">}}</span>\n</code></pre></div>\n</section>\n<section id=\"module-django.views.decorators.csrf\">\n<span id=\"the-decorator-method\"></span><h3>La méthode du décorateur<a class=\"heading-anchor\" href=\"#module-django.views.decorators.csrf\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>Plutôt que d’ajouter <code class=\"docutils literal notranslate\"><span class=\"pre\">CsrfViewMiddleware</span></code> comme une protection générale, vous pouvez utiliser le décorateur <code class=\"docutils literal notranslate\"><span class=\"pre\">csrf_protect</span></code>, qui offre exactement la même fonctionnalité, sur les vues particulières qui ont besoin de la protection. Ce décorateur doit être utilisé <strong>à la fois</strong> sur les vues qui insèrent le jeton CSRF dans leur rendu, et sur celles qui acceptent les données de formulaire POST. (Il s’agit souvent de la même fonction de vue, mais pas toujours).</p>\n<p>Le recours à l’utilisation seule du décorateur <strong>n’est pas recommandé</strong>, car si vous oubliez de l’utiliser, vous aurez un trou de sécurité. La stratégie « ceinture et bretelles » qui consiste à utiliser les deux convient tout à fait et n’entraînera qu’une surcharge minimale.</p>\n<dl class=\"py function\">\n<dt class=\"sig sig-object py\" id=\"django.views.decorators.csrf.csrf_protect\">\n<span class=\"sig-name descname\"><span class=\"pre\">csrf_protect</span></span><span class=\"sig-paren\">(</span><em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">view</span></span></em><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#django.views.decorators.csrf.csrf_protect\"><span class=\"visually-hidden\">Lien vers cette définition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd><p>Décorateur qui fournit la protection similaire à l’intergiciel <code class=\"docutils literal notranslate\"><span class=\"pre\">CsrfViewMiddleware</span></code> pour une vue.</p>\n<p>Utilisation :</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.views.decorators.csrf</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">csrf_protect</span>\n<span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.shortcuts</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">render</span>\n\n<span class=\"nd\">@csrf_protect</span>\n<span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">my_view</span><span class=\"p\">(</span><span class=\"n\">request</span><span class=\"p\">):</span>\n    <span class=\"n\">c</span> <span class=\"o\">=</span> <span class=\"p\">{}</span>\n    <span class=\"c1\"># ...</span>\n    <span class=\"k\">return</span> <span class=\"n\">render</span><span class=\"p\">(</span><span class=\"n\">request</span><span class=\"p\">,</span> <span class=\"s2\">&quot;a_template.html&quot;</span><span class=\"p\">,</span> <span class=\"n\">c</span><span class=\"p\">)</span>\n</code></pre></div>\n<p>Si vous utilisez des vues fondées sur les classes, vous pouvez vous référer à la <a class=\"reference internal\" href=\"/fr/1.9/topics/class-based-views/intro/#id1\"><span class=\"std std-ref\">Décoration des vues fondées sur les classes</span></a>.</p>\n</dd></dl>\n\n</section>\n</section>\n<section id=\"rejected-requests\">\n<h2>Requêtes rejetées<a class=\"heading-anchor\" href=\"#rejected-requests\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>Par défaut, une réponse de type « 403 Forbidden » est renvoyée à l’utilisateur si une requête entrante ne satisfait pas les contrôles effectués par <code class=\"docutils literal notranslate\"><span class=\"pre\">CsrfViewMiddleware</span></code>. Ça ne devrait généralement apparaître que lorsqu’il s’agit d’une véritable attaque de type « Cross Site Request Forgery », ou lorsqu’en raison d’une erreur de programmation, le jeton CSRF n’a pas été inclus dans un formulaire de type POST.</p>\n<p>La page d’erreur n’est toutefois pas très sympathique, de sorte que vous pouvez fournir votre propre vue pour traiter cette condition. Pour ce faire, il suffit de définir le réglage <a class=\"reference internal\" href=\"/fr/1.9/ref/settings/#std-setting-CSRF_FAILURE_VIEW\"><code class=\"xref std std-setting docutils literal notranslate\"><span class=\"pre\">CSRF_FAILURE_VIEW</span></code></a>.</p>\n<p>CSRF failures are logged as warnings to the <a class=\"reference internal\" href=\"/fr/1.9/topics/logging/#django-request-logger\"><span class=\"std std-ref\">django.request</span></a>\nlogger.</p>\n</section>\n<section id=\"how-it-works\">\n<span id=\"how-csrf-works\"></span><h2>Fonctionnement<a class=\"heading-anchor\" href=\"#how-it-works\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>La protection CSRF est basée sur les éléments suivants :</p>\n<ol class=\"arabic\">\n<li><p>Un cookie CSRF qui est défini à une valeur aléatoire (un nonce cryptographique indépendant de la session, comme on l’appelle), auquelle les autres sites n’auront pas accès.</p>\n<p>Ce cookie est créé par l’intergiciel <code class=\"docutils literal notranslate\"><span class=\"pre\">CsrfViewMiddleware</span></code>. Il est destiné à être permanent, mais comme il n’est pas possible d’installer un cookie qui n’expire jamais, il est envoyé avec chaque réponse qui a appelé <code class=\"docutils literal notranslate\"><span class=\"pre\">django.middleware.csrf.get_token()</span></code> (la fonction utilisée en interne pour récupérer le jeton CSRF).</p>\n<p>For security reasons, the value of the CSRF cookie is changed each time a\nuser logs in.</p>\n</li>\n<li><p>Un champ de formulaire masqué avec le nom « csrfmiddlewaretoken » est présent dans tous les formulaires POST affichés. La valeur de ce champ correspond à la valeur du cookie CSRF.</p>\n<p>Cette action est effectuée par la balise de gabarit.</p>\n</li>\n<li><p>Pour toutes les requêtes entrantes qui n’utilisent pas les méthodes HTTP GET, HEAD, OPTIONS ou TRACE, un cookie CSRF doit être présent, et le champ « csrfmiddlewaretoken » doit être présent et correct. Si ce n’est pas le cas, l’utilisateur obtiendra une erreur 403.</p>\n<p>Cette vérification est effectuée par l’intergiciel <code class=\"docutils literal notranslate\"><span class=\"pre\">CsrfViewMiddleware</span></code>.</p>\n</li>\n<li><p>De plus, pour les requêtes HTTPS, le contrôle strict du référant est effectué par <code class=\"docutils literal notranslate\"><span class=\"pre\">CsrfViewMiddleware</span></code>. Cela signifie que même si un sous-domaine peut définir ou modifier des cookies pour votre domaine, il ne peut pas forcer un utilisateur à envoyer des données à votre application car cette requête ne viendrait pas de votre domaine exact.</p>\n<p>Cela protège aussi contre une attaque de type « Man-In-The-Middle » qui est possible sous HTTPS lors de l’utilisation d’un nonce cryptographique indépendant de la session, parce que les en-têtes HTTP <code class=\"docutils literal notranslate\"><span class=\"pre\">Set-Cookie</span></code> sont (malheureusement) acceptés par les clients, même quand ils parlent à un site en HTTPS. (La vérification du référant n’est pas faite pour les requêtes HTTP car la présence de l’en-tête <code class=\"docutils literal notranslate\"><span class=\"pre\">Referer</span></code> n’est pas suffisamment fiable sous HTTP.)</p>\n<p>Si le réglage <a class=\"reference internal\" href=\"/fr/1.9/ref/settings/#std-setting-CSRF_COOKIE_DOMAIN\"><code class=\"xref std std-setting docutils literal notranslate\"><span class=\"pre\">CSRF_COOKIE_DOMAIN</span></code></a> est défini, le référant est comparé avec lui. Ce réglage prend en compte les sous-domaines. Par exemple, <code class=\"docutils literal notranslate\"><span class=\"pre\">CSRF_COOKIE_DOMAIN</span> <span class=\"pre\">=</span> <span class=\"pre\">'.exemple.com'</span></code> autorise les requêtes POST depuis <code class=\"docutils literal notranslate\"><span class=\"pre\">www.exemple.com</span></code> et <code class=\"docutils literal notranslate\"><span class=\"pre\">api.exemple.com</span></code>. Si le réglage n’est pas défini, le référant doit alors correspondre à l’en-tête HTTP <code class=\"docutils literal notranslate\"><span class=\"pre\">Host</span></code>.</p>\n<p>L’extension des référants acceptés au-delà de l’hôte courant ou du domaine du cookie peut se faire avec le réglage <a class=\"reference internal\" href=\"/fr/1.9/ref/settings/#std-setting-CSRF_TRUSTED_ORIGINS\"><code class=\"xref std std-setting docutils literal notranslate\"><span class=\"pre\">CSRF_TRUSTED_ORIGINS</span></code></a>.</p>\n</li>\n</ol>\n<p>Cela garantit que seuls les formulaires originaires de domaines de confiance peuvent être utilisés pour renvoyer des données avec une requête POST.</p>\n<p>It deliberately ignores GET requests (and other requests that are defined as\n“safe” by <span class=\"target\" id=\"index-1\"></span><a class=\"rfc reference external\" href=\"https://datatracker.ietf.org/doc/html/rfc7231.html\"><strong>RFC 7231</strong></a>). These requests ought never to have any potentially\ndangerous side effects , and so a CSRF attack with a GET request ought to be\nharmless. <span class=\"target\" id=\"index-2\"></span><a class=\"rfc reference external\" href=\"https://datatracker.ietf.org/doc/html/rfc7231.html\"><strong>RFC 7231</strong></a> defines POST, PUT, and DELETE as “unsafe”, and all other\nmethods are also assumed to be unsafe, for maximum protection.</p>\n<p>La protection CRSF ne peut pas protéger contre les attaques de « l’homme du milieu », c’est pourquoi il faut utiliser <a class=\"reference internal\" href=\"/fr/1.9/topics/security/#security-recommendation-ssl\"><span class=\"std std-ref\">HTTPS</span></a> avec <a class=\"reference internal\" href=\"/fr/1.9/ref/middleware/#http-strict-transport-security\"><span class=\"std std-ref\">Sécurité de transport HTTP stricte (HSTS)</span></a>. Il suppose également la <a class=\"reference internal\" href=\"/fr/1.9/topics/security/#host-headers-virtual-hosting\"><span class=\"std std-ref\">validation de l’en-tête HOST</span></a> et que le site ne comporte pas de <a class=\"reference internal\" href=\"/fr/1.9/topics/security/#cross-site-scripting\"><span class=\"std std-ref\">vulnérabilités de scripts inter-sites</span></a> (parce que ce type de vulnérabilité permet déjà à un attaquant de faire ce qu’une vulnérabilité CSRF permet de faire, et plus encore).</p>\n<aside class=\"version-note version-changed\" data-version=\"1.9\">\n<p class=\"version-note-title\">Changed in Django 1.9</p><p>Le contrôle en fonction du réglage <a class=\"reference internal\" href=\"/fr/1.9/ref/settings/#std-setting-CSRF_COOKIE_DOMAIN\"><code class=\"xref std std-setting docutils literal notranslate\"><span class=\"pre\">CSRF_COOKIE_DOMAIN</span></code></a> a été ajouté.</p>\n</aside>\n</section>\n<section id=\"caching\">\n<h2>Mise en cache<a class=\"heading-anchor\" href=\"#caching\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>Si la balise de gabarit <a class=\"reference internal\" href=\"/fr/1.9/ref/templates/builtins/#std-templatetag-csrf_token\"><code class=\"xref std std-ttag docutils literal notranslate\"><span class=\"pre\">csrf_token</span></code></a> est utilisée par un gabarit (ou que la fonction <code class=\"docutils literal notranslate\"><span class=\"pre\">get_token</span></code> est appelée d’une autre façon), l’intergiciel <code class=\"docutils literal notranslate\"><span class=\"pre\">CsrfViewMiddleware</span></code> ajoute un cookie et un en-tête <code class=\"docutils literal notranslate\"><span class=\"pre\">Vary:</span> <span class=\"pre\">Cookie</span></code> à la réponse. Cela signifie que l’intergiciel fonctionnera bien avec l’intergiciel de cache s’il est utilisé conformément aux instructions (<code class=\"docutils literal notranslate\"><span class=\"pre\">UpdateCacheMiddleware</span></code> doit être placé dans les réglages avant tout autre intergiciel).</p>\n<p>Toutefois, si vous utilisez des décorateurs de cache sur des vues individuelles, l’intergiciel CSRF n’aura pas encore pu définir l’en-tête Vary ou le cookie CSRF, et la réponse sera mise en cache sans l’un ni l’autre. Dans ce cas, sur les vues qui nécessitent qu’un jeton CSRF soit inséré, vous devez utiliser le décorateur de fonction <a class=\"reference internal\" href=\"#django.views.decorators.csrf.csrf_protect\" title=\"django.views.decorators.csrf.csrf_protect\"><code class=\"xref py py-func docutils literal notranslate\"><span class=\"pre\">django.views.decorators.csrf.csrf_protect()</span></code></a> en premier :</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.views.decorators.cache</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">cache_page</span>\n<span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.views.decorators.csrf</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">csrf_protect</span>\n\n<span class=\"nd\">@cache_page</span><span class=\"p\">(</span><span class=\"mi\">60</span> <span class=\"o\">*</span> <span class=\"mi\">15</span><span class=\"p\">)</span>\n<span class=\"nd\">@csrf_protect</span>\n<span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">my_view</span><span class=\"p\">(</span><span class=\"n\">request</span><span class=\"p\">):</span>\n    <span class=\"o\">...</span>\n</code></pre></div>\n<p>Si vous utilisez des vues fondées sur les classes, vous pouvez vous référer à la <a class=\"reference internal\" href=\"/fr/1.9/topics/class-based-views/intro/#id1\"><span class=\"std std-ref\">Décoration des vues fondées sur les classes</span></a>.</p>\n</section>\n<section id=\"testing\">\n<h2>Tests<a class=\"heading-anchor\" href=\"#testing\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>Généralement, <code class=\"docutils literal notranslate\"><span class=\"pre\">CsrfViewMiddleware</span></code> gêne les tests des fonctions de vues, parce que le jeton CSRF doit être envoyé avec chaque requête POST. Le client HTTP de Django utilisé pour les tests a donc été modifié afin de marquer automatiquement les requêtes et ainsi d’informer l’intergiciel et le décorateur <code class=\"docutils literal notranslate\"><span class=\"pre\">csrf_protect</span></code> de manière à ce qu’ils ne rejettent pas ces requêtes. À tous les autres égards (par exemple, l’envoi des cookies, etc.), le comportement durant les tests est identique.</p>\n<p>Si pour une raison quelconque vous <em>voulez</em> que le client HTTP utilisé pour les tests effectue des contrôles CSRF, vous pouvez créer une instance du client de test qui applique les vérifications CSRF :</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"gp\">&gt;&gt;&gt; </span><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.test</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">Client</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">csrf_client</span> <span class=\"o\">=</span> <span class=\"n\">Client</span><span class=\"p\">(</span><span class=\"n\">enforce_csrf_checks</span><span class=\"o\">=</span><span class=\"kc\">True</span><span class=\"p\">)</span>\n</code></pre></div>\n</section>\n<section id=\"limitations\">\n<span id=\"csrf-limitations\"></span><h2>Limitations<a class=\"heading-anchor\" href=\"#limitations\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>Les sous-domaines d’un site peuvent placer des cookies sur le client pour l’ensemble du domaine. En définissant le cookie et en utilisant le jeton correspondant, les sous-domaines seront en mesure de contourner la protection CSRF. La seule façon d’éviter cela est de s’assurer que les sous-domaines sont contrôlés par des utilisateurs de confiance (ou, au moins ne sont pas en mesure de définir des cookies). Notez que même sans CSRF, il existe d’autres vulnérabilités, comme la fixation de session, qui font que donner des sous-domaines à des tierces parties non sûres est une mauvaise idée ; ces vulnérabilités ne peuvent pas facilement être résolues avec les navigateurs actuels.</p>\n</section>\n<section id=\"edge-cases\">\n<h2>Cas particuliers<a class=\"heading-anchor\" href=\"#edge-cases\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>Certaines vues peuvent avoir des exigences inhabituelles qui impliquent qu’elles ne correspondent pas au modèle normal envisagé ici. Un certain nombre d’utilitaires peuvent être utiles dans ces situations. Les scénarios qui pourraient alors être nécessaires sont décrits dans la section suivante.</p>\n<section id=\"utilities\">\n<h3>Utilitaires<a class=\"heading-anchor\" href=\"#utilities\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>Les exemples ci-dessous s’appliquent à des vues basées sur des fonctions. Si vous utilisez des vues fondées sur les classes, vous pouvez vous référer à la <a class=\"reference internal\" href=\"/fr/1.9/topics/class-based-views/intro/#id1\"><span class=\"std std-ref\">Décoration des vues fondées sur les classes</span></a>.</p>\n<dl class=\"py function\">\n<dt class=\"sig sig-object py\" id=\"django.views.decorators.csrf.csrf_exempt\">\n<span class=\"sig-name descname\"><span class=\"pre\">csrf_exempt</span></span><span class=\"sig-paren\">(</span><em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">view</span></span></em><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#django.views.decorators.csrf.csrf_exempt\"><span class=\"visually-hidden\">Lien vers cette définition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd><p>Ce décorateur marque une vue comme étant exempte de la protection assurée par l’intergiciel. Exemple :</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.views.decorators.csrf</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">csrf_exempt</span>\n<span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.http</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">HttpResponse</span>\n\n<span class=\"nd\">@csrf_exempt</span>\n<span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">my_view</span><span class=\"p\">(</span><span class=\"n\">request</span><span class=\"p\">):</span>\n    <span class=\"k\">return</span> <span class=\"n\">HttpResponse</span><span class=\"p\">(</span><span class=\"s1\">&#39;Hello world&#39;</span><span class=\"p\">)</span>\n</code></pre></div>\n</dd></dl>\n\n<dl class=\"py function\">\n<dt class=\"sig sig-object py\" id=\"django.views.decorators.csrf.requires_csrf_token\">\n<span class=\"sig-name descname\"><span class=\"pre\">requires_csrf_token</span></span><span class=\"sig-paren\">(</span><em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">view</span></span></em><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#django.views.decorators.csrf.requires_csrf_token\"><span class=\"visually-hidden\">Lien vers cette définition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd><p>Normalement, la balise de gabarit <a class=\"reference internal\" href=\"/fr/1.9/ref/templates/builtins/#std-templatetag-csrf_token\"><code class=\"xref std std-ttag docutils literal notranslate\"><span class=\"pre\">csrf_token</span></code></a> ne fonctionnera pas si  <code class=\"docutils literal notranslate\"><span class=\"pre\">CsrfViewMiddleware.process_view</span></code> ou un équivalent comme  <code class=\"docutils literal notranslate\"><span class=\"pre\">csrf_protect</span></code> n’a pas été utilisé. Le décorateur de vue <code class=\"docutils literal notranslate\"><span class=\"pre\">requires_csrf_token</span></code> peut être utilisé pour s’assurer que la balise de gabarit fonctionne. Ce décorateur fonctionne de façon similaire à <code class=\"docutils literal notranslate\"><span class=\"pre\">csrf_protect</span></code>, mais ne rejette jamais une demande entrante.</p>\n<p>Exemple :</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.views.decorators.csrf</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">requires_csrf_token</span>\n<span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.shortcuts</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">render</span>\n\n<span class=\"nd\">@requires_csrf_token</span>\n<span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">my_view</span><span class=\"p\">(</span><span class=\"n\">request</span><span class=\"p\">):</span>\n    <span class=\"n\">c</span> <span class=\"o\">=</span> <span class=\"p\">{}</span>\n    <span class=\"c1\"># ...</span>\n    <span class=\"k\">return</span> <span class=\"n\">render</span><span class=\"p\">(</span><span class=\"n\">request</span><span class=\"p\">,</span> <span class=\"s2\">&quot;a_template.html&quot;</span><span class=\"p\">,</span> <span class=\"n\">c</span><span class=\"p\">)</span>\n</code></pre></div>\n</dd></dl>\n\n<dl class=\"py function\">\n<dt class=\"sig sig-object py\" id=\"django.views.decorators.csrf.ensure_csrf_cookie\">\n<span class=\"sig-name descname\"><span class=\"pre\">ensure_csrf_cookie</span></span><span class=\"sig-paren\">(</span><em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">view</span></span></em><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#django.views.decorators.csrf.ensure_csrf_cookie\"><span class=\"visually-hidden\">Lien vers cette définition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd><p>Ce décorateur force une vue à envoyer le cookie CSRF.</p>\n</dd></dl>\n\n</section>\n<section id=\"scenarios\">\n<h3>Scénarios<a class=\"heading-anchor\" href=\"#scenarios\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h3>\n<section id=\"csrf-protection-should-be-disabled-for-just-a-few-views\">\n<h4>La protection CSRF doit être désactivée pour quelques vues<a class=\"heading-anchor\" href=\"#csrf-protection-should-be-disabled-for-just-a-few-views\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h4>\n<p>La plupart des vues nécessitent une protection CSRF, mais quelques-unes n’en ont pas besoin.</p>\n<p>Solution : plutôt que de désactiver l’intergiciel et d’appliquer <code class=\"docutils literal notranslate\"><span class=\"pre\">csrf_protect</span></code> à toutes les vues qui en ont besoin, activez l’intergiciel et utilisez <a class=\"reference internal\" href=\"#django.views.decorators.csrf.csrf_exempt\" title=\"django.views.decorators.csrf.csrf_exempt\"><code class=\"xref py py-func docutils literal notranslate\"><span class=\"pre\">csrf_exempt()</span></code></a>.</p>\n</section>\n<section id=\"csrfviewmiddleware-process-view-not-used\">\n<h4>CsrfViewMiddleware.process_view non utilisé<a class=\"heading-anchor\" href=\"#csrfviewmiddleware-process-view-not-used\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h4>\n<p>Il y a des cas où <code class=\"docutils literal notranslate\"><span class=\"pre\">CsrfViewMiddleware.process_view</span></code> n’aura pas été exécuté avant votre vue - les gestionnaires d’erreurs 404 et 500, par exemple - mais vous avez quand même besoin du jeton CSRF dans un formulaire.</p>\n<p>Solution : utilisez <a class=\"reference internal\" href=\"#django.views.decorators.csrf.requires_csrf_token\" title=\"django.views.decorators.csrf.requires_csrf_token\"><code class=\"xref py py-func docutils literal notranslate\"><span class=\"pre\">requires_csrf_token()</span></code></a></p>\n</section>\n<section id=\"unprotected-view-needs-the-csrf-token\">\n<h4>Une vue non protégée nécessite le jeton CSRF<a class=\"heading-anchor\" href=\"#unprotected-view-needs-the-csrf-token\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h4>\n<p>Certaines vues peuvent ne pas être protégées, peut-être exemptées par <code class=\"docutils literal notranslate\"><span class=\"pre\">csrf_exempt</span></code>, mais ont tout de même besoin d’inclure le jeton CSRF.</p>\n<p>Solution : utilisez <a class=\"reference internal\" href=\"#django.views.decorators.csrf.csrf_exempt\" title=\"django.views.decorators.csrf.csrf_exempt\"><code class=\"xref py py-func docutils literal notranslate\"><span class=\"pre\">csrf_exempt()</span></code></a> suivi de <a class=\"reference internal\" href=\"#django.views.decorators.csrf.requires_csrf_token\" title=\"django.views.decorators.csrf.requires_csrf_token\"><code class=\"xref py py-func docutils literal notranslate\"><span class=\"pre\">requires_csrf_token()</span></code></a> (c’est à dire que <code class=\"docutils literal notranslate\"><span class=\"pre\">requires_csrf_token</span></code> doit être le décorateur le plus à l’intérieur).</p>\n</section>\n<section id=\"view-needs-protection-for-one-path\">\n<h4>Une vue a besoin de protection pour un chemin particulier<a class=\"heading-anchor\" href=\"#view-needs-protection-for-one-path\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h4>\n<p>Une vue a besoin de protection CSRF seulement quand un certain nombre de conditions sont remplies, et ne doit pas être protégée le reste du temps.</p>\n<p>Solution : utilisez <a class=\"reference internal\" href=\"#django.views.decorators.csrf.csrf_exempt\" title=\"django.views.decorators.csrf.csrf_exempt\"><code class=\"xref py py-func docutils literal notranslate\"><span class=\"pre\">csrf_exempt()</span></code></a> pour l’ensemble de la fonction de vue, et <a class=\"reference internal\" href=\"#django.views.decorators.csrf.csrf_protect\" title=\"django.views.decorators.csrf.csrf_protect\"><code class=\"xref py py-func docutils literal notranslate\"><span class=\"pre\">csrf_protect()</span></code></a> spécifiquement pour le chemin qui doit être protégé. Exemple :</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.views.decorators.csrf</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">csrf_exempt</span><span class=\"p\">,</span> <span class=\"n\">csrf_protect</span>\n\n<span class=\"nd\">@csrf_exempt</span>\n<span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">my_view</span><span class=\"p\">(</span><span class=\"n\">request</span><span class=\"p\">):</span>\n\n    <span class=\"nd\">@csrf_protect</span>\n    <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">protected_path</span><span class=\"p\">(</span><span class=\"n\">request</span><span class=\"p\">):</span>\n        <span class=\"n\">do_something</span><span class=\"p\">()</span>\n\n    <span class=\"k\">if</span> <span class=\"n\">some_condition</span><span class=\"p\">():</span>\n       <span class=\"k\">return</span> <span class=\"n\">protected_path</span><span class=\"p\">(</span><span class=\"n\">request</span><span class=\"p\">)</span>\n    <span class=\"k\">else</span><span class=\"p\">:</span>\n       <span class=\"n\">do_something_else</span><span class=\"p\">()</span>\n</code></pre></div>\n</section>\n<section id=\"page-uses-ajax-without-any-html-form\">\n<h4>Une page utilise de l’AJAX sans aucun formulaire HTML<a class=\"heading-anchor\" href=\"#page-uses-ajax-without-any-html-form\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h4>\n<p>Une page effectue une requête POST via AJAX, et cette page n’a pas de formulaire HTML avec une balise <a class=\"reference internal\" href=\"/fr/1.9/ref/templates/builtins/#std-templatetag-csrf_token\"><code class=\"xref std std-ttag docutils literal notranslate\"><span class=\"pre\">csrf_token</span></code></a> qui provoquerait la transmission du cookie CSRF.</p>\n<p>Solution : utilisez <a class=\"reference internal\" href=\"#django.views.decorators.csrf.ensure_csrf_cookie\" title=\"django.views.decorators.csrf.ensure_csrf_cookie\"><code class=\"xref py py-func docutils literal notranslate\"><span class=\"pre\">ensure_csrf_cookie()</span></code></a> sur la vue qui envoie la page.</p>\n</section>\n</section>\n</section>\n<section id=\"contrib-and-reusable-apps\">\n<h2>Applications intégrées et applications réutilisables<a class=\"heading-anchor\" href=\"#contrib-and-reusable-apps\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>Comme il est possible pour le développeur de désactiver l’intergiciel <code class=\"docutils literal notranslate\"><span class=\"pre\">CsrfViewMiddleware</span></code>, toutes les vues concernées dans les applications « contrib » de Django utilisent le décorateur <code class=\"docutils literal notranslate\"><span class=\"pre\">csrf_protect</span></code> pour garantir la protection de ces applications contre les attaques CSRF. Il est recommandé que les développeurs d’autres applications réutilisables qui souhaitent offrir les mêmes garanties utilisent également le décorateur <code class=\"docutils literal notranslate\"><span class=\"pre\">csrf_protect</span></code> sur leurs vues.</p>\n</section>\n<section id=\"settings\">\n<h2>Réglages<a class=\"heading-anchor\" href=\"#settings\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>Un certain nombre de réglages peuvent être utilisés pour contrôler le comportement anti-CSRF de Django :</p>\n<ul class=\"simple\">\n<li><p><a class=\"reference internal\" href=\"/fr/1.9/ref/settings/#std-setting-CSRF_COOKIE_AGE\"><code class=\"xref std std-setting docutils literal notranslate\"><span class=\"pre\">CSRF_COOKIE_AGE</span></code></a></p></li>\n<li><p><a class=\"reference internal\" href=\"/fr/1.9/ref/settings/#std-setting-CSRF_COOKIE_DOMAIN\"><code class=\"xref std std-setting docutils literal notranslate\"><span class=\"pre\">CSRF_COOKIE_DOMAIN</span></code></a></p></li>\n<li><p><a class=\"reference internal\" href=\"/fr/1.9/ref/settings/#std-setting-CSRF_COOKIE_HTTPONLY\"><code class=\"xref std std-setting docutils literal notranslate\"><span class=\"pre\">CSRF_COOKIE_HTTPONLY</span></code></a></p></li>\n<li><p><a class=\"reference internal\" href=\"/fr/1.9/ref/settings/#std-setting-CSRF_COOKIE_NAME\"><code class=\"xref std std-setting docutils literal notranslate\"><span class=\"pre\">CSRF_COOKIE_NAME</span></code></a></p></li>\n<li><p><a class=\"reference internal\" href=\"/fr/1.9/ref/settings/#std-setting-CSRF_COOKIE_PATH\"><code class=\"xref std std-setting docutils literal notranslate\"><span class=\"pre\">CSRF_COOKIE_PATH</span></code></a></p></li>\n<li><p><a class=\"reference internal\" href=\"/fr/1.9/ref/settings/#std-setting-CSRF_COOKIE_SECURE\"><code class=\"xref std std-setting docutils literal notranslate\"><span class=\"pre\">CSRF_COOKIE_SECURE</span></code></a></p></li>\n<li><p><a class=\"reference internal\" href=\"/fr/1.9/ref/settings/#std-setting-CSRF_FAILURE_VIEW\"><code class=\"xref std std-setting docutils literal notranslate\"><span class=\"pre\">CSRF_FAILURE_VIEW</span></code></a></p></li>\n<li><p><a class=\"reference internal\" href=\"/fr/1.9/ref/settings/#std-setting-CSRF_HEADER_NAME\"><code class=\"xref std std-setting docutils literal notranslate\"><span class=\"pre\">CSRF_HEADER_NAME</span></code></a></p></li>\n<li><p><a class=\"reference internal\" href=\"/fr/1.9/ref/settings/#std-setting-CSRF_TRUSTED_ORIGINS\"><code class=\"xref std std-setting docutils literal notranslate\"><span class=\"pre\">CSRF_TRUSTED_ORIGINS</span></code></a></p></li>\n</ul>\n</section>\n<section id=\"frequently-asked-questions\">\n<h2>Questions fréquentes<a class=\"heading-anchor\" href=\"#frequently-asked-questions\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h2>\n<section id=\"is-posting-an-arbitrary-csrf-token-pair-cookie-and-post-data-a-vulnerability\">\n<h3>Est-ce que l’envoi d’une paire de jetons CSRF arbitraires (cookie et données POST) est une vulnérabilité ?<a class=\"heading-anchor\" href=\"#is-posting-an-arbitrary-csrf-token-pair-cookie-and-post-data-a-vulnerability\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>Non, délibérément pas. Sans attaque de « l’homme du milieu », il n’existe aucune possibilité pour un attaquant d’envoyer un cookie de jeton CSRF à destination du navigateur de sa victime ; une attaque réussie devrait pouvoir obtenir le cookie du navigateur de la victime par XSS ou autre moyen similaire, auquel cas l’attaquant n’a généralement pas besoin d’attaquer par CSRF.</p>\n<p>Certains outils d’audit de sécurité le signalent comme un problème, mais comme mentionné ci-dessus, un attaquant ne peut pas voler un cookie CSRF du navigateur d’un utilisateur. Pouvoir « voler » ou modifier son propre jeton à l’aide de Firebug, des outils de développement Chrome, etc. ne signifie pas qu’il s’agit d’une vulnérabilité.</p>\n</section>\n<section id=\"is-the-fact-that-django-s-csrf-protection-isn-t-linked-to-a-session-a-problem\">\n<h3>Le fait que la protection CSRF de Django n’est pas liée à une session pose-t-il un problème ?<a class=\"heading-anchor\" href=\"#is-the-fact-that-django-s-csrf-protection-isn-t-linked-to-a-session-a-problem\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>Non, délibérément pas. Le fait de ne pas lier la protection CSRF à une session permet d’utiliser la protection sur des sites qui autorisent des envois de données par des utilisateurs anonymes et qui n’ont pas de session.</p>\n</section>\n<section id=\"why-not-use-a-new-token-for-each-request\">\n<h3>Pourquoi ne pas utiliser un nouveau jeton pour chaque requête ?<a class=\"heading-anchor\" href=\"#why-not-use-a-new-token-for-each-request\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>La génération d’un nouveau jeton pour chaque requête est problématique d’un point de vue interface utilisateur car cela invalide tous les formulaires précédents. Les utilisateurs seraient très mécontents de constater que l’ouverture d’un nouvel onglet de votre site rend invalide le formulaire qu’ils viennent de remplir patiemment dans un autre onglet, ou qu’un formulaire accédé en utilisant le bouton retour ne puisse plus être rempli.</p>\n</section>\n<section id=\"why-might-a-user-encounter-a-csrf-validation-failure-after-logging-in\">\n<h3>Why might a user encounter a CSRF validation failure after logging in?<a class=\"heading-anchor\" href=\"#why-might-a-user-encounter-a-csrf-validation-failure-after-logging-in\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>For security reasons, CSRF tokens are rotated each time a user logs in. Any\npage with a form generated before a login will have an old, invalid CSRF token\nand need to be reloaded. This might happen if a user uses the back button after\na login or if they log in in a different browser tab.</p>\n</section>\n</section>","rootId":"module-django.middleware.csrf","toc":[{"title":"Comment l’utiliser","anchor":"how-to-use-it","children":[{"title":"AJAX","anchor":"ajax","children":[]},{"title":"Using CSRF in Jinja2 templates","anchor":"using-csrf-in-jinja2-templates","children":[]},{"title":"La méthode du décorateur","anchor":"module-django.views.decorators.csrf","children":[]}]},{"title":"Requêtes rejetées","anchor":"rejected-requests","children":[]},{"title":"Fonctionnement","anchor":"how-it-works","children":[]},{"title":"Mise en cache","anchor":"caching","children":[]},{"title":"Tests","anchor":"testing","children":[]},{"title":"Limitations","anchor":"limitations","children":[]},{"title":"Cas particuliers","anchor":"edge-cases","children":[{"title":"Utilitaires","anchor":"utilities","children":[]},{"title":"Scénarios","anchor":"scenarios","children":[{"title":"La protection CSRF doit être désactivée pour quelques vues","anchor":"csrf-protection-should-be-disabled-for-just-a-few-views","children":[]},{"title":"CsrfViewMiddleware.process_view non utilisé","anchor":"csrfviewmiddleware-process-view-not-used","children":[]},{"title":"Une vue non protégée nécessite le jeton CSRF","anchor":"unprotected-view-needs-the-csrf-token","children":[]},{"title":"Une vue a besoin de protection pour un chemin particulier","anchor":"view-needs-protection-for-one-path","children":[]},{"title":"Une page utilise de l’AJAX sans aucun formulaire HTML","anchor":"page-uses-ajax-without-any-html-form","children":[]}]}]},{"title":"Applications intégrées et applications réutilisables","anchor":"contrib-and-reusable-apps","children":[]},{"title":"Réglages","anchor":"settings","children":[]},{"title":"Questions fréquentes","anchor":"frequently-asked-questions","children":[{"title":"Est-ce que l’envoi d’une paire de jetons CSRF arbitraires (cookie et données POST) est une vulnérabilité ?","anchor":"is-posting-an-arbitrary-csrf-token-pair-cookie-and-post-data-a-vulnerability","children":[]},{"title":"Le fait que la protection CSRF de Django n’est pas liée à une session pose-t-il un problème ?","anchor":"is-the-fact-that-django-s-csrf-protection-isn-t-linked-to-a-session-a-problem","children":[]},{"title":"Pourquoi ne pas utiliser un nouveau jeton pour chaque requête ?","anchor":"why-not-use-a-new-token-for-each-request","children":[]},{"title":"Why might a user encounter a CSRF validation failure after logging in?","anchor":"why-might-a-user-encounter-a-csrf-validation-failure-after-logging-in","children":[]}]}],"breadcrumbs":[{"docname":"ref/index","title":"Référence de l’API","url":"/fr/1.9/ref/"}],"prev":{"docname":"ref/contrib/webdesign","title":"django.contrib.webdesign","url":"/fr/1.9/ref/contrib/webdesign/"},"next":{"docname":"ref/databases","title":"Bases de données","url":"/fr/1.9/ref/databases/"},"formats":{"html":"/fr/1.9/ref/csrf/","markdown":"/fr/1.9/ref/csrf.md","json":"/fr/1.9/ref/csrf.json"},"source":"https://github.com/django/django/blob/stable/1.9.x/docs/ref/csrf.txt","official":"https://docs.djangoproject.com/fr/1.9/ref/csrf/","inVersions":["6.1","6.0","5.2","5.1","5.0","4.2","4.1","4.0","3.2","3.1","3.0","2.2","2.1","2.0","1.11","1.10","1.9"],"inLocales":["en","fr","ja","id","pt-br","es"]}