summaryrefslogtreecommitdiff
path: root/docs
diff options
context:
space:
mode:
authortommcn <tommcn@mcnamer.ca>2022-03-15 21:19:48 -0400
committerMariusz Felisiak <felisiak.mariusz@gmail.com>2022-03-17 06:53:53 +0100
commite458abc5931861e72f18b5d218726f9add7028cd (patch)
tree976a1fa39d04a20abfb7e9aafcedf42a38e3cb58 /docs
parent8e633906403853868bcd7df62ba30a86151a944d (diff)
Refs #28592 -- Created a new CSRF how-to document.
Diffstat (limited to 'docs')
-rw-r--r--docs/howto/csrf.txt309
-rw-r--r--docs/howto/index.txt1
-rw-r--r--docs/ref/csrf.txt350
3 files changed, 329 insertions, 331 deletions
diff --git a/docs/howto/csrf.txt b/docs/howto/csrf.txt
new file mode 100644
index 0000000000..eb39c94717
--- /dev/null
+++ b/docs/howto/csrf.txt
@@ -0,0 +1,309 @@
+.. _using-csrf:
+
+===================================
+How to use Django's CSRF protection
+===================================
+
+To take advantage of CSRF protection in your views, follow these steps:
+
+#. The CSRF middleware is activated by default in the :setting:`MIDDLEWARE`
+ setting. If you override that setting, remember that
+ ``'django.middleware.csrf.CsrfViewMiddleware'`` should come before any view
+ middleware that assume that CSRF attacks have been dealt with.
+
+ If you disabled it, which is not recommended, you can use
+ :func:`~django.views.decorators.csrf.csrf_protect` on particular views
+ you want to protect (see below).
+
+#. In any template that uses a POST form, use the :ttag:`csrf_token` tag inside
+ the ``<form>`` element if the form is for an internal URL, e.g.:
+
+ .. code-block:: html+django
+
+ <form method="post">{% csrf_token %}
+
+ This should not be done for POST forms that target external URLs, since
+ that would cause the CSRF token to be leaked, leading to a vulnerability.
+
+#. In the corresponding view functions, ensure that
+ :class:`~django.template.RequestContext` is used to render the response so
+ that ``{% csrf_token %}`` will work properly. If you're using the
+ :func:`~django.shortcuts.render` function, generic views, or contrib apps,
+ you are covered already since these all use ``RequestContext``.
+
+.. _csrf-ajax:
+
+AJAX
+====
+
+While the above method can be used for AJAX POST requests, it has some
+inconveniences: you have to remember to pass the CSRF token in as POST data with
+every POST request. For this reason, there is an alternative method: on each
+XMLHttpRequest, set a custom ``X-CSRFToken`` header (as specified by the
+:setting:`CSRF_HEADER_NAME` setting) to the value of the CSRF token. This is
+often easier because many JavaScript frameworks provide hooks that allow
+headers to be set on every request.
+
+First, you must get the CSRF token. How to do that depends on whether or not
+the :setting:`CSRF_USE_SESSIONS` and :setting:`CSRF_COOKIE_HTTPONLY` settings
+are enabled.
+
+.. _acquiring-csrf-token-from-cookie:
+
+Acquiring the token if :setting:`CSRF_USE_SESSIONS` and :setting:`CSRF_COOKIE_HTTPONLY` are ``False``
+-----------------------------------------------------------------------------------------------------
+
+The recommended source for the token is the ``csrftoken`` cookie, which will be
+set if you've enabled CSRF protection for your views as outlined above.
+
+The CSRF token cookie is named ``csrftoken`` by default, but you can control
+the cookie name via the :setting:`CSRF_COOKIE_NAME` setting.
+
+You can acquire the token like this:
+
+.. code-block:: javascript
+
+ function getCookie(name) {
+ let cookieValue = null;
+ if (document.cookie && document.cookie !== '') {
+ const cookies = document.cookie.split(';');
+ for (let i = 0; i < cookies.length; i++) {
+ const cookie = cookies[i].trim();
+ // Does this cookie string begin with the name we want?
+ if (cookie.substring(0, name.length + 1) === (name + '=')) {
+ cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
+ break;
+ }
+ }
+ }
+ return cookieValue;
+ }
+ const csrftoken = getCookie('csrftoken');
+
+The above code could be simplified by using the `JavaScript Cookie library
+<https://github.com/js-cookie/js-cookie/>`_ to replace ``getCookie``:
+
+.. code-block:: javascript
+
+ const csrftoken = Cookies.get('csrftoken');
+
+.. note::
+
+ The CSRF token is also present in the DOM in a masked form, but only if
+ explicitly included using :ttag:`csrf_token` in a template. The cookie
+ contains the canonical, unmasked token. The
+ :class:`~django.middleware.csrf.CsrfViewMiddleware` will accept either.
+ However, in order to protect against `BREACH`_ attacks, it's recommended to
+ use a masked token.
+
+.. warning::
+
+ If your view is not rendering a template containing the :ttag:`csrf_token`
+ template tag, Django might not set the CSRF token cookie. This is common in
+ cases where forms are dynamically added to the page. To address this case,
+ Django provides a view decorator which forces setting of the cookie:
+ :func:`~django.views.decorators.csrf.ensure_csrf_cookie`.
+
+.. _BREACH: http://breachattack.com/
+
+.. _acquiring-csrf-token-from-html:
+
+Acquiring the token if :setting:`CSRF_USE_SESSIONS` or :setting:`CSRF_COOKIE_HTTPONLY` is ``True``
+--------------------------------------------------------------------------------------------------
+
+If you activate :setting:`CSRF_USE_SESSIONS` or
+:setting:`CSRF_COOKIE_HTTPONLY`, you must include the CSRF token in your HTML
+and read the token from the DOM with JavaScript:
+
+.. code-block:: html+django
+
+ {% csrf_token %}
+ <script>
+ const csrftoken = document.querySelector('[name=csrfmiddlewaretoken]').value;
+ </script>
+
+Setting the token on the AJAX request
+-------------------------------------
+
+Finally, you'll need to set the header on your AJAX request. Using the
+`fetch()`_ API:
+
+.. code-block:: javascript
+
+ const request = new Request(
+ /* URL */,
+ {
+ method: 'POST',
+ headers: {'X-CSRFToken': csrftoken},
+ mode: 'same-origin' // Do not send CSRF token to another domain.
+ }
+ );
+ fetch(request).then(function(response) {
+ // ...
+ });
+
+.. _fetch(): https://developer.mozilla.org/en-US/docs/Web/API/fetch
+
+Using CSRF protection in Jinja2 templates
+=========================================
+
+Django's :class:`~django.template.backends.jinja2.Jinja2` template backend
+adds ``{{ csrf_input }}`` to the context of all templates which is equivalent
+to ``{% csrf_token %}`` in the Django template language. For example:
+
+.. code-block:: html+jinja
+
+ <form method="post">{{ csrf_input }}
+
+Using the decorator method
+==========================
+
+Rather than adding ``CsrfViewMiddleware`` as a blanket protection, you can use
+the :func:`~django.views.decorators.csrf.csrf_protect` decorator, which has
+exactly the same functionality, on particular views that need the protection.
+It must be used **both** on views that insert the CSRF token in the output, and
+on those that accept the POST form data. (These are often the same view
+function, but not always).
+
+Use of the decorator by itself is **not recommended**, since if you forget to
+use it, you will have a security hole. The 'belt and braces' strategy of using
+both is fine, and will incur minimal overhead.
+
+.. _csrf-rejected-requests:
+
+Handle rejected requests
+========================
+
+By default, a '403 Forbidden' response is sent to the user if an incoming
+request fails the checks performed by ``CsrfViewMiddleware``. This should
+usually only be seen when there is a genuine Cross Site Request Forgery, or
+when, due to a programming error, the CSRF token has not been included with a
+POST form.
+
+The error page, however, is not very friendly, so you may want to provide your
+own view for handling this condition. To do this, set the
+:setting:`CSRF_FAILURE_VIEW` setting.
+
+CSRF failures are logged as warnings to the :ref:`django.security.csrf
+<django-security-logger>` logger.
+
+Caching
+=======
+
+If the :ttag:`csrf_token` template tag is used by a template (or the
+``get_token`` function is called some other way), ``CsrfViewMiddleware`` will
+add a cookie and a ``Vary: Cookie`` header to the response. This means that the
+middleware will play well with the cache middleware if it is used as instructed
+(``UpdateCacheMiddleware`` goes before all other middleware).
+
+However, if you use cache decorators on individual views, the CSRF middleware
+will not yet have been able to set the Vary header or the CSRF cookie, and the
+response will be cached without either one. In this case, on any views that
+will require a CSRF token to be inserted you should use the
+:func:`django.views.decorators.csrf.csrf_protect` decorator first::
+
+ from django.views.decorators.cache import cache_page
+ from django.views.decorators.csrf import csrf_protect
+
+ @cache_page(60 * 15)
+ @csrf_protect
+ def my_view(request):
+ ...
+
+If you are using class-based views, you can refer to :ref:`Decorating
+class-based views<decorating-class-based-views>`.
+
+Testing and CSRF protection
+===========================
+
+The ``CsrfViewMiddleware`` will usually be a big hindrance to testing view
+functions, due to the need for the CSRF token which must be sent with every POST
+request. For this reason, Django's HTTP client for tests has been modified to
+set a flag on requests which relaxes the middleware and the ``csrf_protect``
+decorator so that they no longer rejects requests. In every other respect
+(e.g. sending cookies etc.), they behave the same.
+
+If, for some reason, you *want* the test client to perform CSRF
+checks, you can create an instance of the test client that enforces
+CSRF checks::
+
+ >>> from django.test import Client
+ >>> csrf_client = Client(enforce_csrf_checks=True)
+
+Edge cases
+==========
+
+Certain views can have unusual requirements that mean they don't fit the normal
+pattern envisaged here. A number of utilities can be useful in these
+situations. The scenarios they might be needed in are described in the following
+section.
+
+Disabling CSRF protection for just a few views
+----------------------------------------------
+
+Most views requires CSRF protection, but a few do not.
+
+Solution: rather than disabling the middleware and applying ``csrf_protect`` to
+all the views that need it, enable the middleware and use
+:func:`~django.views.decorators.csrf.csrf_exempt`.
+
+Setting the token when CsrfViewMiddleware.process_view is not used
+------------------------------------------------------------------
+
+There are cases when ``CsrfViewMiddleware.process_view`` may not have run
+before your view is run - 404 and 500 handlers, for example - but you still
+need the CSRF token in a form.
+
+Solution: use :func:`~django.views.decorators.csrf.requires_csrf_token`
+
+Including the CSRF token in an unprotected view
+-----------------------------------------------
+
+There may be some views that are unprotected and have been exempted by
+``csrf_exempt``, but still need to include the CSRF token.
+
+Solution: use :func:`~django.views.decorators.csrf.csrf_exempt` followed by
+:func:`~django.views.decorators.csrf.requires_csrf_token`. (i.e. ``requires_csrf_token``
+should be the innermost decorator).
+
+Protecting a view for only one path
+-----------------------------------
+
+A view needs CSRF protection under one set of conditions only, and mustn't have
+it for the rest of the time.
+
+Solution: use :func:`~django.views.decorators.csrf.csrf_exempt` for the whole
+view function, and :func:`~django.views.decorators.csrf.csrf_protect` for the
+path within it that needs protection. Example::
+
+ from django.views.decorators.csrf import csrf_exempt, csrf_protect
+
+ @csrf_exempt
+ def my_view(request):
+
+ @csrf_protect
+ def protected_path(request):
+ do_something()
+
+ if some_condition():
+ return protected_path(request)
+ else:
+ do_something_else()
+
+Protecting a page that uses AJAX without an HTML form
+-----------------------------------------------------
+
+A page makes a POST request via AJAX, and the page does not have an HTML form
+with a :ttag:`csrf_token` that would cause the required CSRF cookie to be sent.
+
+Solution: use :func:`~django.views.decorators.csrf.ensure_csrf_cookie` on the
+view that sends the page.
+
+Contrib and reusable apps
+=========================
+
+Because it is possible for the developer to turn off the ``CsrfViewMiddleware``,
+all relevant views in contrib apps use the ``csrf_protect`` decorator to ensure
+the security of these applications against CSRF. It is recommended that the
+developers of other reusable apps that want the same guarantees also use the
+``csrf_protect`` decorator on their views.
diff --git a/docs/howto/index.txt b/docs/howto/index.txt
index 75304f6827..05a0203132 100644
--- a/docs/howto/index.txt
+++ b/docs/howto/index.txt
@@ -11,6 +11,7 @@ you quickly accomplish common tasks.
:maxdepth: 1
auth-remote-user
+ csrf
custom-management-commands
custom-model-fields
custom-lookups
diff --git a/docs/ref/csrf.txt b/docs/ref/csrf.txt
index 8cbce28738..360c5a3f47 100644
--- a/docs/ref/csrf.txt
+++ b/docs/ref/csrf.txt
@@ -16,215 +16,10 @@ a site with someone else's credentials, is also covered.
The first defense against CSRF attacks is to ensure that GET requests (and other
'safe' methods, as defined by :rfc:`7231#section-4.2.1`) are side effect free.
Requests via 'unsafe' methods, such as POST, PUT, and DELETE, can then be
-protected by following the steps below.
+protected by the steps outlined in :ref:`using-csrf`.
.. _Cross Site Request Forgeries: https://www.squarefree.com/securitytips/web-developers.html#CSRF
-.. _using-csrf:
-
-How to use it
-=============
-
-To take advantage of CSRF protection in your views, follow these steps:
-
-#. The CSRF middleware is activated by default in the :setting:`MIDDLEWARE`
- setting. If you override that setting, remember that
- ``'django.middleware.csrf.CsrfViewMiddleware'`` should come before any view
- middleware that assume that CSRF attacks have been dealt with.
-
- If you disabled it, which is not recommended, you can use
- :func:`~django.views.decorators.csrf.csrf_protect` on particular views
- you want to protect (see below).
-
-#. In any template that uses a POST form, use the :ttag:`csrf_token` tag inside
- the ``<form>`` element if the form is for an internal URL, e.g.:
-
- .. code-block:: html+django
-
- <form method="post">{% csrf_token %}
-
- This should not be done for POST forms that target external URLs, since
- that would cause the CSRF token to be leaked, leading to a vulnerability.
-
-#. In the corresponding view functions, ensure that
- :class:`~django.template.RequestContext` is used to render the response so
- that ``{% csrf_token %}`` will work properly. If you're using the
- :func:`~django.shortcuts.render` function, generic views, or contrib apps,
- you are covered already since these all use ``RequestContext``.
-
-.. _csrf-ajax:
-
-AJAX
-----
-
-While the above method can be used for AJAX POST requests, it has some
-inconveniences: you have to remember to pass the CSRF token in as POST data with
-every POST request. For this reason, there is an alternative method: on each
-XMLHttpRequest, set a custom ``X-CSRFToken`` header (as specified by the
-:setting:`CSRF_HEADER_NAME` setting) to the value of the CSRF token. This is
-often easier because many JavaScript frameworks provide hooks that allow
-headers to be set on every request.
-
-First, you must get the CSRF token. How to do that depends on whether or not
-the :setting:`CSRF_USE_SESSIONS` and :setting:`CSRF_COOKIE_HTTPONLY` settings
-are enabled.
-
-.. _acquiring-csrf-token-from-cookie:
-
-Acquiring the token if :setting:`CSRF_USE_SESSIONS` and :setting:`CSRF_COOKIE_HTTPONLY` are ``False``
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-The recommended source for the token is the ``csrftoken`` cookie, which will be
-set if you've enabled CSRF protection for your views as outlined above.
-
-The CSRF token cookie is named ``csrftoken`` by default, but you can control
-the cookie name via the :setting:`CSRF_COOKIE_NAME` setting.
-
-You can acquire the token like this:
-
-.. code-block:: javascript
-
- function getCookie(name) {
- let cookieValue = null;
- if (document.cookie && document.cookie !== '') {
- const cookies = document.cookie.split(';');
- for (let i = 0; i < cookies.length; i++) {
- const cookie = cookies[i].trim();
- // Does this cookie string begin with the name we want?
- if (cookie.substring(0, name.length + 1) === (name + '=')) {
- cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
- break;
- }
- }
- }
- return cookieValue;
- }
- const csrftoken = getCookie('csrftoken');
-
-The above code could be simplified by using the `JavaScript Cookie library
-<https://github.com/js-cookie/js-cookie/>`_ to replace ``getCookie``:
-
-.. code-block:: javascript
-
- const csrftoken = Cookies.get('csrftoken');
-
-.. note::
-
- The CSRF token is also present in the DOM in a masked form, but only if
- explicitly included using :ttag:`csrf_token` in a template. The cookie
- contains the canonical, unmasked token. The
- :class:`~django.middleware.csrf.CsrfViewMiddleware` will accept either.
- However, in order to protect against `BREACH`_ attacks, it's recommended to
- use a masked token.
-
-.. warning::
-
- If your view is not rendering a template containing the :ttag:`csrf_token`
- template tag, Django might not set the CSRF token cookie. This is common in
- cases where forms are dynamically added to the page. To address this case,
- Django provides a view decorator which forces setting of the cookie:
- :func:`~django.views.decorators.csrf.ensure_csrf_cookie`.
-
-.. _acquiring-csrf-token-from-html:
-
-Acquiring the token if :setting:`CSRF_USE_SESSIONS` or :setting:`CSRF_COOKIE_HTTPONLY` is ``True``
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-If you activate :setting:`CSRF_USE_SESSIONS` or
-:setting:`CSRF_COOKIE_HTTPONLY`, you must include the CSRF token in your HTML
-and read the token from the DOM with JavaScript:
-
-.. code-block:: html+django
-
- {% csrf_token %}
- <script>
- const csrftoken = document.querySelector('[name=csrfmiddlewaretoken]').value;
- </script>
-
-Setting the token on the AJAX request
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-Finally, you'll need to set the header on your AJAX request. Using the
-`fetch()`_ API:
-
-.. code-block:: javascript
-
- const request = new Request(
- /* URL */,
- {
- method: 'POST',
- headers: {'X-CSRFToken': csrftoken},
- mode: 'same-origin' // Do not send CSRF token to another domain.
- }
- );
- fetch(request).then(function(response) {
- // ...
- });
-
-.. _fetch(): https://developer.mozilla.org/en-US/docs/Web/API/fetch
-
-Using CSRF in Jinja2 templates
-------------------------------
-
-Django's :class:`~django.template.backends.jinja2.Jinja2` template backend
-adds ``{{ csrf_input }}`` to the context of all templates which is equivalent
-to ``{% csrf_token %}`` in the Django template language. For example:
-
-.. code-block:: html+jinja
-
- <form method="post">{{ csrf_input }}
-
-The decorator method
---------------------
-
-.. module:: django.views.decorators.csrf
-
-Rather than adding ``CsrfViewMiddleware`` as a blanket protection, you can use
-the ``csrf_protect`` decorator, which has exactly the same functionality, on
-particular views that need the protection. It must be used **both** on views
-that insert the CSRF token in the output, and on those that accept the POST form
-data. (These are often the same view function, but not always).
-
-Use of the decorator by itself is **not recommended**, since if you forget to
-use it, you will have a security hole. The 'belt and braces' strategy of using
-both is fine, and will incur minimal overhead.
-
-.. function:: csrf_protect(view)
-
- Decorator that provides the protection of ``CsrfViewMiddleware`` to a view.
-
- Usage::
-
- from django.shortcuts import render
- from django.views.decorators.csrf import csrf_protect
-
- @csrf_protect
- def my_view(request):
- c = {}
- # ...
- return render(request, "a_template.html", c)
-
- If you are using class-based views, you can refer to
- :ref:`Decorating class-based views<decorating-class-based-views>`.
-
-.. _csrf-rejected-requests:
-
-Rejected requests
-=================
-
-By default, a '403 Forbidden' response is sent to the user if an incoming
-request fails the checks performed by ``CsrfViewMiddleware``. This should
-usually only be seen when there is a genuine Cross Site Request Forgery, or
-when, due to a programming error, the CSRF token has not been included with a
-POST form.
-
-The error page, however, is not very friendly, so you may want to provide your
-own view for handling this condition. To do this, set the
-:setting:`CSRF_FAILURE_VIEW` setting.
-
-CSRF failures are logged as warnings to the :ref:`django.security.csrf
-<django-security-logger>` logger.
-
.. _how-csrf-works:
How it works
@@ -328,49 +123,6 @@ vulnerability allows and much worse).
.. _Origin header: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Origin
.. _disable the referer: https://www.w3.org/TR/referrer-policy/#referrer-policy-delivery
-Caching
-=======
-
-If the :ttag:`csrf_token` template tag is used by a template (or the
-``get_token`` function is called some other way), ``CsrfViewMiddleware`` will
-add a cookie and a ``Vary: Cookie`` header to the response. This means that the
-middleware will play well with the cache middleware if it is used as instructed
-(``UpdateCacheMiddleware`` goes before all other middleware).
-
-However, if you use cache decorators on individual views, the CSRF middleware
-will not yet have been able to set the Vary header or the CSRF cookie, and the
-response will be cached without either one. In this case, on any views that
-will require a CSRF token to be inserted you should use the
-:func:`django.views.decorators.csrf.csrf_protect` decorator first::
-
- from django.views.decorators.cache import cache_page
- from django.views.decorators.csrf import csrf_protect
-
- @cache_page(60 * 15)
- @csrf_protect
- def my_view(request):
- ...
-
-If you are using class-based views, you can refer to :ref:`Decorating
-class-based views<decorating-class-based-views>`.
-
-Testing
-=======
-
-The ``CsrfViewMiddleware`` will usually be a big hindrance to testing view
-functions, due to the need for the CSRF token which must be sent with every POST
-request. For this reason, Django's HTTP client for tests has been modified to
-set a flag on requests which relaxes the middleware and the ``csrf_protect``
-decorator so that they no longer rejects requests. In every other respect
-(e.g. sending cookies etc.), they behave the same.
-
-If, for some reason, you *want* the test client to perform CSRF
-checks, you can create an instance of the test client that enforces
-CSRF checks::
-
- >>> from django.test import Client
- >>> csrf_client = Client(enforce_csrf_checks=True)
-
.. _csrf-limitations:
Limitations
@@ -384,16 +136,10 @@ to set cookies). Note that even without CSRF, there are other vulnerabilities,
such as session fixation, that make giving subdomains to untrusted parties a bad
idea, and these vulnerabilities cannot easily be fixed with current browsers.
-Edge cases
-==========
-
-Certain views can have unusual requirements that mean they don't fit the normal
-pattern envisaged here. A number of utilities can be useful in these
-situations. The scenarios they might be needed in are described in the following
-section.
-
Utilities
----------
+=========
+
+.. module:: django.views.decorators.csrf
The examples below assume you are using function-based views. If you
are working with class-based views, you can refer to :ref:`Decorating
@@ -411,6 +157,21 @@ class-based views<decorating-class-based-views>`.
def my_view(request):
return HttpResponse('Hello world')
+.. function:: csrf_protect(view)
+
+ Decorator that provides the protection of ``CsrfViewMiddleware`` to a view.
+
+ Usage::
+
+ from django.shortcuts import render
+ from django.views.decorators.csrf import csrf_protect
+
+ @csrf_protect
+ def my_view(request):
+ c = {}
+ # ...
+ return render(request, "a_template.html", c)
+
.. function:: requires_csrf_token(view)
Normally the :ttag:`csrf_token` template tag will not work if
@@ -434,79 +195,6 @@ class-based views<decorating-class-based-views>`.
This decorator forces a view to send the CSRF cookie.
-Scenarios
----------
-
-CSRF protection should be disabled for just a few views
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-Most views requires CSRF protection, but a few do not.
-
-Solution: rather than disabling the middleware and applying ``csrf_protect`` to
-all the views that need it, enable the middleware and use
-:func:`~django.views.decorators.csrf.csrf_exempt`.
-
-CsrfViewMiddleware.process_view not used
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-There are cases when ``CsrfViewMiddleware.process_view`` may not have run
-before your view is run - 404 and 500 handlers, for example - but you still
-need the CSRF token in a form.
-
-Solution: use :func:`~django.views.decorators.csrf.requires_csrf_token`
-
-Unprotected view needs the CSRF token
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-There may be some views that are unprotected and have been exempted by
-``csrf_exempt``, but still need to include the CSRF token.
-
-Solution: use :func:`~django.views.decorators.csrf.csrf_exempt` followed by
-:func:`~django.views.decorators.csrf.requires_csrf_token`. (i.e. ``requires_csrf_token``
-should be the innermost decorator).
-
-View needs protection for one path
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-A view needs CSRF protection under one set of conditions only, and mustn't have
-it for the rest of the time.
-
-Solution: use :func:`~django.views.decorators.csrf.csrf_exempt` for the whole
-view function, and :func:`~django.views.decorators.csrf.csrf_protect` for the
-path within it that needs protection. Example::
-
- from django.views.decorators.csrf import csrf_exempt, csrf_protect
-
- @csrf_exempt
- def my_view(request):
-
- @csrf_protect
- def protected_path(request):
- do_something()
-
- if some_condition():
- return protected_path(request)
- else:
- do_something_else()
-
-Page uses AJAX without any HTML form
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-A page makes a POST request via AJAX, and the page does not have an HTML form
-with a :ttag:`csrf_token` that would cause the required CSRF cookie to be sent.
-
-Solution: use :func:`~django.views.decorators.csrf.ensure_csrf_cookie` on the
-view that sends the page.
-
-Contrib and reusable apps
-=========================
-
-Because it is possible for the developer to turn off the ``CsrfViewMiddleware``,
-all relevant views in contrib apps use the ``csrf_protect`` decorator to ensure
-the security of these applications against CSRF. It is recommended that the
-developers of other reusable apps that want the same guarantees also use the
-``csrf_protect`` decorator on their views.
-
Settings
========