From 2411b8b5eb65fe3d7bcc1ee1f59e2433520c7df6 Mon Sep 17 00:00:00 2001 From: Tim Graham Date: Sat, 2 Jan 2021 18:46:17 -0500 Subject: Fixed #16010 -- Added Origin header checking to CSRF middleware. Thanks David Benjamin for the original patch, and Florian Apolloner, Chris Jerdonek, and Adam Johnson for reviews. --- docs/ref/csrf.txt | 18 ++++++++++++++---- docs/ref/settings.txt | 19 +++++++++++++------ 2 files changed, 27 insertions(+), 10 deletions(-) (limited to 'docs/ref') diff --git a/docs/ref/csrf.txt b/docs/ref/csrf.txt index 175cbb7da0..6e340bcdeb 100644 --- a/docs/ref/csrf.txt +++ b/docs/ref/csrf.txt @@ -263,10 +263,15 @@ The CSRF protection is based on the following things: This check is done by ``CsrfViewMiddleware``. -#. In addition, for HTTPS requests, strict referer checking is done by - ``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. +#. ``CsrfViewMiddleware`` verifies the `Origin header`_, if provided by the + browser, against the current host and the :setting:`CSRF_TRUSTED_ORIGINS` + setting. This provides protection against cross-subdomain attacks. + +#. In addition, for HTTPS requests, if the ``Origin`` header isn't provided, + ``CsrfViewMiddleware`` performs strict referer checking. 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 secret, due to the fact that HTTP @@ -284,6 +289,10 @@ The CSRF protection is based on the following things: Expanding the accepted referers beyond the current host or cookie domain can be done with the :setting:`CSRF_TRUSTED_ORIGINS` setting. +.. versionadded:: 4.0 + + ``Origin`` checking was added, as described above. + This ensures that only forms that have originated from trusted domains can be used to POST data back. @@ -314,6 +323,7 @@ vulnerability allows and much worse). sites. .. _BREACH: http://breachattack.com/ +.. _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 diff --git a/docs/ref/settings.txt b/docs/ref/settings.txt index 704bee63a4..5c938f26f1 100644 --- a/docs/ref/settings.txt +++ b/docs/ref/settings.txt @@ -459,13 +459,18 @@ Default: ``[]`` (Empty list) A list of trusted origins for unsafe requests (e.g. ``POST``). +For requests that include the ``Origin`` header, Django's CSRF protection +requires that header match the origin present in the ``Host`` header. + For a :meth:`secure ` unsafe -request, Django's CSRF protection requires that the request have a ``Referer`` -header that matches the origin present in the ``Host`` header. This prevents, -for example, a ``POST`` request from ``subdomain.example.com`` from succeeding -against ``api.example.com``. If you need cross-origin unsafe requests over -HTTPS, continuing the example, add ``'https://subdomain.example.com'`` to this -list (and/or ``http://...`` if requests originate from an insecure page). +request that doesn't include the ``Origin`` header, the request must have a +``Referer`` header that matches the origin present in the ``Host`` header. + +These checks prevent, for example, a ``POST`` request from +``subdomain.example.com`` from succeeding against ``api.example.com``. If you +need cross-origin unsafe requests, continuing the example, add +``'https://subdomain.example.com'`` to this list (and/or ``http://...`` if +requests originate from an insecure page). The setting also supports subdomains, so you could add ``'https://*.example.com'``, for example, to allow access from all subdomains @@ -476,6 +481,8 @@ of ``example.com``. The values in older versions must only include the hostname (possibly with a leading dot) and not the scheme or an asterisk. + Also, ``Origin`` header checking isn't performed in older versions. + .. setting:: DATABASES ``DATABASES`` -- cgit v1.3