Browse Source

Fixed #30862 -- Allowed setting SameSite cookies flags to 'none'.

Thanks Florian Apolloner and Carlton Gibson for reviews.
Osaetin Daniel 5 years ago
parent
commit
b33bfc3839

+ 2 - 2
django/http/response.py

@@ -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):

+ 11 - 0
docs/ref/request-response.txt

@@ -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

+ 16 - 1
docs/ref/settings.txt

@@ -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
 

+ 13 - 3
docs/releases/3.1.txt

@@ -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
 ~~~~~~~~~~~~~
 

+ 4 - 1
tests/responses/test_cookie.py

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