Fixed #26165 -- Added some FAQs about CSRF protection.

Thanks Florian Apolloner and Shai Berger for review.
This commit is contained in:
acemaster 2016-02-03 23:59:45 +05:30 committed by Tim Graham
parent 11a8207d42
commit a1b1688c7d
1 changed files with 50 additions and 7 deletions

View File

@ -240,12 +240,16 @@ The CSRF protection is based on the following things:
This check is done by ``CsrfViewMiddleware``.
4. In addition, for HTTPS requests, strict referer checking is done by
``CsrfViewMiddleware``. This is necessary to address a Man-In-The-Middle
attack that is possible under HTTPS when using a session independent nonce,
due to the fact that HTTP 'Set-Cookie' headers are (unfortunately) accepted
by clients that are talking to a site under HTTPS. (Referer checking is not
done for HTTP requests because the presence of the Referer header is not
reliable enough under HTTP.)
``CsrfViewMiddleware``. This means that even if a subdomain can set or
modify cookies on your domain, it can't force a user to post to your
application since that request won't come from your own exact domain.
This also addresses a man-in-the-middle attack that's possible under HTTPS
when using a session independent nonce, due to the fact that HTTP
``Set-Cookie`` headers are (unfortunately) accepted by clients even when
they are talking to a site under HTTPS. (Referer checking is not done for
HTTP requests because the presence of the ``Referer`` header isn't reliable
enough under HTTP.)
If the :setting:`CSRF_COOKIE_DOMAIN` setting is set, the referer is compared
against it. This setting supports subdomains. For example,
@ -263,7 +267,15 @@ It deliberately ignores GET requests (and other requests that are defined as
'safe' by :rfc:`2616`). These requests ought never to have any potentially
dangerous side effects , and so a CSRF attack with a GET request ought to be
harmless. :rfc:`2616` defines POST, PUT and DELETE as 'unsafe', and all other
methods are assumed to be unsafe, for maximum protection.
methods are also assumed to be unsafe, for maximum protection.
The CSRF protection cannot protect against man-in-the-middle attacks, so use
:ref:`HTTPS <security-recommendation-ssl>` with
:ref:`http-strict-transport-security`. It also assumes :ref:`validation of
the HOST header <host-headers-virtual-hosting>` and that there aren't any
:ref:`cross-site scripting vulnerabilities <cross-site-scripting>` on your site
(because XSS vulnerabilities already let an attacker do anything a CSRF
vulnerability allows and much worse).
.. versionchanged:: 1.9
@ -462,3 +474,34 @@ A number of settings can be used to control Django's CSRF behavior:
* :setting:`CSRF_FAILURE_VIEW`
* :setting:`CSRF_HEADER_NAME`
* :setting:`CSRF_TRUSTED_ORIGINS`
Frequently Asked Questions
==========================
Is posting an arbitrary CSRF token pair (cookie and POST data) a vulnerability?
-------------------------------------------------------------------------------
No, this is by design. Without a man-in-the-middle attack, there is no way for
an attacker to send a CSRF token cookie to a victim's browser, so a successful
attack would need to obtain the victim's browser's cookie via XSS or similar,
in which case an attacker usually doesn't need CSRF attacks.
Some security audit tools flag this as a problem but as mentioned before, an
attacker cannot steal a user's browser's CSRF cookie. "Stealing" or modifying
*your own* token using Firebug, Chrome dev tools, etc. isn't a vulnerability.
Is the fact that Django's CSRF protection isn't linked to a session a problem?
------------------------------------------------------------------------------
No, this is by design. Not linking CSRF protection to a session allows using
the protection on sites such as a `pastebin` that allow submissions from
anonymous users which don't have a session.
Why not use a new token for each request?
-----------------------------------------
Generating a new token for each request is problematic from a UI perspective
because it invalidates all previous forms. Most users would be very unhappy to
find that opening a new tab on your site has invalidated the form they had
just spent time filling out in another tab or that a form they accessed via
the back button could not be filled out.