2
0

csrf.txt 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242
  1. =====================================
  2. Cross Site Request Forgery protection
  3. =====================================
  4. .. module:: django.middleware.csrf
  5. :synopsis: Protects against Cross Site Request Forgeries
  6. The CSRF middleware and template tag provides easy-to-use protection against
  7. `Cross Site Request Forgeries`_. This type of attack occurs when a malicious
  8. website contains a link, a form button or some JavaScript that is intended to
  9. perform some action on your website, using the credentials of a logged-in user
  10. who visits the malicious site in their browser. A related type of attack,
  11. 'login CSRF', where an attacking site tricks a user's browser into logging into
  12. a site with someone else's credentials, is also covered.
  13. The first defense against CSRF attacks is to ensure that GET requests (and other
  14. 'safe' methods, as defined by :rfc:`9110#section-9.2.1`) are side effect free.
  15. Requests via 'unsafe' methods, such as POST, PUT, and DELETE, can then be
  16. protected by the steps outlined in :ref:`using-csrf`.
  17. .. _Cross Site Request Forgeries: https://owasp.org/www-community/attacks/csrf#overview
  18. .. _how-csrf-works:
  19. How it works
  20. ============
  21. The CSRF protection is based on the following things:
  22. #. A CSRF cookie that is a random secret value, which other sites will not have
  23. access to.
  24. ``CsrfViewMiddleware`` sends this cookie with the response whenever
  25. ``django.middleware.csrf.get_token()`` is called. It can also send it in
  26. other cases. For security reasons, the value of the secret is changed each
  27. time a user logs in.
  28. #. A hidden form field with the name 'csrfmiddlewaretoken', present in all
  29. outgoing POST forms.
  30. In order to protect against `BREACH`_ attacks, the value of this field is
  31. not simply the secret. It is scrambled differently with each response using
  32. a mask. The mask is generated randomly on every call to ``get_token()``, so
  33. the form field value is different each time.
  34. This part is done by the :ttag:`csrf_token` template tag.
  35. #. For all incoming requests that are not using HTTP GET, HEAD, OPTIONS or
  36. TRACE, a CSRF cookie must be present, and the 'csrfmiddlewaretoken' field
  37. must be present and correct. If it isn't, the user will get a 403 error.
  38. When validating the 'csrfmiddlewaretoken' field value, only the secret,
  39. not the full token, is compared with the secret in the cookie value.
  40. This allows the use of ever-changing tokens. While each request may use its
  41. own token, the secret remains common to all.
  42. This check is done by ``CsrfViewMiddleware``.
  43. #. ``CsrfViewMiddleware`` verifies the `Origin header`_, if provided by the
  44. browser, against the current host and the :setting:`CSRF_TRUSTED_ORIGINS`
  45. setting. This provides protection against cross-subdomain attacks.
  46. #. In addition, for HTTPS requests, if the ``Origin`` header isn't provided,
  47. ``CsrfViewMiddleware`` performs strict referer checking. This means that
  48. even if a subdomain can set or modify cookies on your domain, it can't force
  49. a user to post to your application since that request won't come from your
  50. own exact domain.
  51. This also addresses a man-in-the-middle attack that's possible under HTTPS
  52. when using a session independent secret, due to the fact that HTTP
  53. ``Set-Cookie`` headers are (unfortunately) accepted by clients even when
  54. they are talking to a site under HTTPS. (Referer checking is not done for
  55. HTTP requests because the presence of the ``Referer`` header isn't reliable
  56. enough under HTTP.)
  57. If the :setting:`CSRF_COOKIE_DOMAIN` setting is set, the referer is compared
  58. against it. You can allow cross-subdomain requests by including a leading
  59. dot. For example, ``CSRF_COOKIE_DOMAIN = '.example.com'`` will allow POST
  60. requests from ``www.example.com`` and ``api.example.com``. If the setting is
  61. not set, then the referer must match the HTTP ``Host`` header.
  62. Expanding the accepted referers beyond the current host or cookie domain can
  63. be done with the :setting:`CSRF_TRUSTED_ORIGINS` setting.
  64. This ensures that only forms that have originated from trusted domains can be
  65. used to POST data back.
  66. It deliberately ignores GET requests (and other requests that are defined as
  67. 'safe' by :rfc:`9110#section-9.2.1`). These requests ought never to have any
  68. potentially dangerous side effects, and so a CSRF attack with a GET request
  69. ought to be harmless. :rfc:`9110#section-9.2.1` defines POST, PUT, and DELETE
  70. as 'unsafe', and all other methods are also assumed to be unsafe, for maximum
  71. protection.
  72. The CSRF protection cannot protect against man-in-the-middle attacks, so use
  73. :ref:`HTTPS <security-recommendation-ssl>` with
  74. :ref:`http-strict-transport-security`. It also assumes :ref:`validation of
  75. the HOST header <host-headers-virtual-hosting>` and that there aren't any
  76. :ref:`cross-site scripting vulnerabilities <cross-site-scripting>` on your site
  77. (because XSS vulnerabilities already let an attacker do anything a CSRF
  78. vulnerability allows and much worse).
  79. .. admonition:: Removing the ``Referer`` header
  80. To avoid disclosing the referrer URL to third-party sites, you might want
  81. to `disable the referer`_ on your site's ``<a>`` tags. For example, you
  82. might use the ``<meta name="referrer" content="no-referrer">`` tag or
  83. include the ``Referrer-Policy: no-referrer`` header. Due to the CSRF
  84. protection's strict referer checking on HTTPS requests, those techniques
  85. cause a CSRF failure on requests with 'unsafe' methods. Instead, use
  86. alternatives like ``<a rel="noreferrer" ...>"`` for links to third-party
  87. sites.
  88. .. _BREACH: https://www.breachattack.com/
  89. .. _Origin header: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Origin
  90. .. _disable the referer: https://www.w3.org/TR/referrer-policy/#referrer-policy-delivery
  91. .. _csrf-limitations:
  92. Limitations
  93. ===========
  94. Subdomains within a site will be able to set cookies on the client for the whole
  95. domain. By setting the cookie and using a corresponding token, subdomains will
  96. be able to circumvent the CSRF protection. The only way to avoid this is to
  97. ensure that subdomains are controlled by trusted users (or, are at least unable
  98. to set cookies). Note that even without CSRF, there are other vulnerabilities,
  99. such as session fixation, that make giving subdomains to untrusted parties a bad
  100. idea, and these vulnerabilities cannot easily be fixed with current browsers.
  101. Utilities
  102. =========
  103. .. module:: django.views.decorators.csrf
  104. The examples below assume you are using function-based views. If you
  105. are working with class-based views, you can refer to :ref:`Decorating
  106. class-based views<decorating-class-based-views>`.
  107. .. function:: csrf_exempt(view)
  108. This decorator marks a view as being exempt from the protection ensured by
  109. the middleware. Example::
  110. from django.http import HttpResponse
  111. from django.views.decorators.csrf import csrf_exempt
  112. @csrf_exempt
  113. def my_view(request):
  114. return HttpResponse("Hello world")
  115. .. function:: csrf_protect(view)
  116. Decorator that provides the protection of
  117. :class:`~django.middleware.csrf.CsrfViewMiddleware` to a view.
  118. Usage::
  119. from django.shortcuts import render
  120. from django.views.decorators.csrf import csrf_protect
  121. @csrf_protect
  122. def my_view(request):
  123. c = {}
  124. # ...
  125. return render(request, "a_template.html", c)
  126. .. function:: requires_csrf_token(view)
  127. Normally the :ttag:`csrf_token` template tag will not work if
  128. ``CsrfViewMiddleware.process_view`` or an equivalent like ``csrf_protect``
  129. has not run. The view decorator ``requires_csrf_token`` can be used to
  130. ensure the template tag does work. This decorator works similarly to
  131. ``csrf_protect``, but never rejects an incoming request.
  132. Example::
  133. from django.shortcuts import render
  134. from django.views.decorators.csrf import requires_csrf_token
  135. @requires_csrf_token
  136. def my_view(request):
  137. c = {}
  138. # ...
  139. return render(request, "a_template.html", c)
  140. .. function:: ensure_csrf_cookie(view)
  141. This decorator forces a view to send the CSRF cookie.
  142. Settings
  143. ========
  144. A number of settings can be used to control Django's CSRF behavior:
  145. * :setting:`CSRF_COOKIE_AGE`
  146. * :setting:`CSRF_COOKIE_DOMAIN`
  147. * :setting:`CSRF_COOKIE_HTTPONLY`
  148. * :setting:`CSRF_COOKIE_NAME`
  149. * :setting:`CSRF_COOKIE_PATH`
  150. * :setting:`CSRF_COOKIE_SAMESITE`
  151. * :setting:`CSRF_COOKIE_SECURE`
  152. * :setting:`CSRF_FAILURE_VIEW`
  153. * :setting:`CSRF_HEADER_NAME`
  154. * :setting:`CSRF_TRUSTED_ORIGINS`
  155. * :setting:`CSRF_USE_SESSIONS`
  156. Frequently Asked Questions
  157. ==========================
  158. Is posting an arbitrary CSRF token pair (cookie and POST data) a vulnerability?
  159. -------------------------------------------------------------------------------
  160. No, this is by design. Without a man-in-the-middle attack, there is no way for
  161. an attacker to send a CSRF token cookie to a victim's browser, so a successful
  162. attack would need to obtain the victim's browser's cookie via XSS or similar,
  163. in which case an attacker usually doesn't need CSRF attacks.
  164. Some security audit tools flag this as a problem but as mentioned before, an
  165. attacker cannot steal a user's browser's CSRF cookie. "Stealing" or modifying
  166. *your own* token using Firebug, Chrome dev tools, etc. isn't a vulnerability.
  167. Is it a problem that Django's CSRF protection isn't linked to a session by default?
  168. -----------------------------------------------------------------------------------
  169. No, this is by design. Not linking CSRF protection to a session allows using
  170. the protection on sites such as a *pastebin* that allow submissions from
  171. anonymous users which don't have a session.
  172. If you wish to store the CSRF token in the user's session, use the
  173. :setting:`CSRF_USE_SESSIONS` setting.
  174. Why might a user encounter a CSRF validation failure after logging in?
  175. ----------------------------------------------------------------------
  176. For security reasons, CSRF tokens are rotated each time a user logs in. Any
  177. page with a form generated before a login will have an old, invalid CSRF token
  178. and need to be reloaded. This might happen if a user uses the back button after
  179. a login or if they log in a different browser tab.