Fixed #30862 -- Allowed setting SameSite cookies flags to 'none'.
Thanks Florian Apolloner and Carlton Gibson for reviews.
This commit is contained in:
parent
14e690ae5a
commit
b33bfc3839
|
@ -197,8 +197,8 @@ class HttpResponseBase:
|
|||
if httponly:
|
||||
self.cookies[key]['httponly'] = True
|
||||
if samesite:
|
||||
if samesite.lower() not in ('lax', 'strict'):
|
||||
raise ValueError('samesite must be "lax" or "strict".')
|
||||
if samesite.lower() not in ('lax', 'none', 'strict'):
|
||||
raise ValueError('samesite must be "lax", "none", or "strict".')
|
||||
self.cookies[key]['samesite'] = samesite
|
||||
|
||||
def setdefault(self, key, value):
|
||||
|
|
|
@ -833,9 +833,16 @@ Methods
|
|||
isn't supported by all browsers, so it's not a replacement for Django's
|
||||
CSRF protection, but rather a defense in depth measure.
|
||||
|
||||
Use ``samesite='None'`` (string) to explicitly state that this cookie is
|
||||
sent with all same-site and cross-site requests.
|
||||
|
||||
.. _HttpOnly: https://www.owasp.org/index.php/HttpOnly
|
||||
.. _SameSite: https://www.owasp.org/index.php/SameSite
|
||||
|
||||
.. versionchanged:: 3.1
|
||||
|
||||
Using ``samesite='None'`` (string) was allowed.
|
||||
|
||||
.. warning::
|
||||
|
||||
:rfc:`RFC 6265 <6265#section-6.1>` states that user agents should
|
||||
|
@ -853,6 +860,10 @@ Methods
|
|||
you will need to remember to pass it to the corresponding
|
||||
:meth:`HttpRequest.get_signed_cookie` call.
|
||||
|
||||
.. versionchanged:: 3.1
|
||||
|
||||
Using ``samesite='None'`` (string) was allowed.
|
||||
|
||||
.. method:: HttpResponse.delete_cookie(key, path='/', domain=None)
|
||||
|
||||
Deletes the cookie with the given key. Fails silently if the key doesn't
|
||||
|
|
|
@ -383,6 +383,10 @@ cookie from being sent in cross-site requests.
|
|||
|
||||
See :setting:`SESSION_COOKIE_SAMESITE` for details about ``SameSite``.
|
||||
|
||||
.. versionchanged:: 3.1
|
||||
|
||||
Setting ``CSRF_COOKIE_SAMESITE = 'None'`` was allowed.
|
||||
|
||||
.. setting:: CSRF_COOKIE_SECURE
|
||||
|
||||
``CSRF_COOKIE_SECURE``
|
||||
|
@ -1862,6 +1866,10 @@ cookie from being sent in cross-site requests.
|
|||
|
||||
See :setting:`SESSION_COOKIE_SAMESITE` for details about ``SameSite``.
|
||||
|
||||
.. versionchanged:: 3.1
|
||||
|
||||
Setting ``LANGUAGE_COOKIE_SAMESITE = 'None'`` was allowed.
|
||||
|
||||
.. setting:: LANGUAGE_COOKIE_SECURE
|
||||
|
||||
``LANGUAGE_COOKIE_SECURE``
|
||||
|
@ -3208,7 +3216,14 @@ Possible values for the setting are:
|
|||
regular link from an external website and be blocked in CSRF-prone request
|
||||
methods (e.g. ``POST``).
|
||||
|
||||
* ``None``: disables the flag.
|
||||
* ``'None'`` (string): the session cookie will be sent with all same-site and
|
||||
cross-site requests.
|
||||
|
||||
* ``False``: disables the flag.
|
||||
|
||||
.. versionchanged:: 3.1
|
||||
|
||||
Setting ``SESSION_COOKIE_SAMESITE = 'None'`` was allowed.
|
||||
|
||||
.. _SameSite: https://www.owasp.org/index.php/SameSite
|
||||
|
||||
|
|
|
@ -105,7 +105,9 @@ Minor features
|
|||
:mod:`django.contrib.sessions`
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
* ...
|
||||
* The :setting:`SESSION_COOKIE_SAMESITE` setting now allows ``'None'`` (string)
|
||||
value to explicitly state that the cookie is sent with all same-site and
|
||||
cross-site requests.
|
||||
|
||||
:mod:`django.contrib.sitemaps`
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
@ -141,7 +143,9 @@ Cache
|
|||
CSRF
|
||||
~~~~
|
||||
|
||||
* ...
|
||||
* The :setting:`CSRF_COOKIE_SAMESITE` setting now allows ``'None'`` (string)
|
||||
value to explicitly state that the cookie is sent with all same-site and
|
||||
cross-site requests.
|
||||
|
||||
Email
|
||||
~~~~~
|
||||
|
@ -173,7 +177,9 @@ Generic Views
|
|||
Internationalization
|
||||
~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
* ...
|
||||
* The :setting:`LANGUAGE_COOKIE_SAMESITE` setting now allows ``'None'``
|
||||
(string) value to explicitly state that the cookie is sent with all same-site
|
||||
and cross-site requests.
|
||||
|
||||
Logging
|
||||
~~~~~~~
|
||||
|
@ -232,6 +238,10 @@ Requests and Responses
|
|||
* If :setting:`ALLOWED_HOSTS` is empty and ``DEBUG=True``, subdomains of
|
||||
localhost are now allowed in the ``Host`` header, e.g. ``static.localhost``.
|
||||
|
||||
* :meth:`.HttpResponse.set_cookie` and :meth:`.HttpResponse.set_signed_cookie`
|
||||
now allow using ``samesite='None'`` (string) to explicitly state that the
|
||||
cookie is sent with all same-site and cross-site requests.
|
||||
|
||||
Serialization
|
||||
~~~~~~~~~~~~~
|
||||
|
||||
|
|
|
@ -81,13 +81,16 @@ class SetCookieTests(SimpleTestCase):
|
|||
|
||||
def test_samesite(self):
|
||||
response = HttpResponse()
|
||||
response.set_cookie('example', samesite='None')
|
||||
self.assertEqual(response.cookies['example']['samesite'], 'None')
|
||||
response.set_cookie('example', samesite='Lax')
|
||||
self.assertEqual(response.cookies['example']['samesite'], 'Lax')
|
||||
response.set_cookie('example', samesite='strict')
|
||||
self.assertEqual(response.cookies['example']['samesite'], 'strict')
|
||||
|
||||
def test_invalid_samesite(self):
|
||||
with self.assertRaisesMessage(ValueError, 'samesite must be "lax" or "strict".'):
|
||||
msg = 'samesite must be "lax", "none", or "strict".'
|
||||
with self.assertRaisesMessage(ValueError, msg):
|
||||
HttpResponse().set_cookie('example', samesite='invalid')
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue