mirror of
				https://github.com/django/django.git
				synced 2025-10-31 09:41:08 +00:00 
			
		
		
		
	Fixed #30862 -- Allowed setting SameSite cookies flags to 'none'.
Thanks Florian Apolloner and Carlton Gibson for reviews.
This commit is contained in:
		
				
					committed by
					
						 Mariusz Felisiak
						Mariusz Felisiak
					
				
			
			
				
	
			
			
			
						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') | ||||
|  | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user