Skip to content

Commit

Permalink
Fixed #30862 -- Allowed setting SameSite cookies flags to 'none'.
Browse files Browse the repository at this point in the history
Thanks Florian Apolloner and Carlton Gibson for reviews.
  • Loading branch information
danidee10 authored and felixxm committed Dec 12, 2019
1 parent 14e690a commit b33bfc3
Show file tree
Hide file tree
Showing 5 changed files with 46 additions and 7 deletions.
4 changes: 2 additions & 2 deletions django/http/response.py
Original file line number Diff line number Diff line change
Expand Up @@ -197,8 +197,8 @@ def set_cookie(self, key, value='', max_age=None, expires=None, path='/',
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):
Expand Down
11 changes: 11 additions & 0 deletions docs/ref/request-response.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand Down
17 changes: 16 additions & 1 deletion docs/ref/settings.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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``
Expand Down Expand Up @@ -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``
Expand Down Expand Up @@ -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

Expand Down
16 changes: 13 additions & 3 deletions docs/releases/3.1.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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`
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Expand Down Expand Up @@ -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
~~~~~
Expand Down Expand Up @@ -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
~~~~~~~
Expand Down Expand Up @@ -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
~~~~~~~~~~~~~

Expand Down
5 changes: 4 additions & 1 deletion tests/responses/test_cookie.py
Original file line number Diff line number Diff line change
Expand Up @@ -81,13 +81,16 @@ def test_unicode_cookie(self):

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')


Expand Down

0 comments on commit b33bfc3

Please sign in to comment.