summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMariusz Felisiak <felisiak.mariusz@gmail.com>2020-07-16 09:30:15 +0200
committerMariusz Felisiak <felisiak.mariusz@gmail.com>2020-07-16 09:35:35 +0200
commitf1a6e6c817f3205ea7da6f973f51524ff630dda5 (patch)
tree0c68c7a7ddcea7000cb2f83f636397f3ac7d7b0b
parent6f09ee2be3c0ce07b096af7ac63b64ee7cfc23cf (diff)
downloaddjango-f1a6e6c817f3205ea7da6f973f51524ff630dda5.tar.gz
[2.2.x] Fixed #31790 -- Fixed setting SameSite cookies flag in HttpResponse.delete_cookie().
Cookies with the "SameSite" flag set to None and without the "secure" flag will be soon rejected by latest browser versions. This affects sessions and messages cookies. Backport of 331324ecce1330dce3dbd1713203cb9a42854ad7 from stable/3.0.x
-rw-r--r--django/contrib/messages/storage/cookie.py6
-rw-r--r--django/contrib/sessions/middleware.py1
-rw-r--r--django/http/response.py4
-rw-r--r--docs/ref/request-response.txt6
-rw-r--r--docs/releases/2.2.15.txt13
-rw-r--r--docs/releases/index.txt1
-rw-r--r--tests/messages_tests/test_cookie.py5
-rw-r--r--tests/responses/test_cookie.py6
-rw-r--r--tests/sessions_tests/tests.py6
9 files changed, 42 insertions, 6 deletions
diff --git a/django/contrib/messages/storage/cookie.py b/django/contrib/messages/storage/cookie.py
index 9e0c93e436..057d573d3f 100644
--- a/django/contrib/messages/storage/cookie.py
+++ b/django/contrib/messages/storage/cookie.py
@@ -89,7 +89,11 @@ class CookieStorage(BaseStorage):
samesite=settings.SESSION_COOKIE_SAMESITE,
)
else:
- response.delete_cookie(self.cookie_name, domain=settings.SESSION_COOKIE_DOMAIN)
+ response.delete_cookie(
+ self.cookie_name,
+ domain=settings.SESSION_COOKIE_DOMAIN,
+ samesite=settings.SESSION_COOKIE_SAMESITE,
+ )
def _store(self, messages, response, remove_oldest=True, *args, **kwargs):
"""
diff --git a/django/contrib/sessions/middleware.py b/django/contrib/sessions/middleware.py
index 6795354cc5..a464b44245 100644
--- a/django/contrib/sessions/middleware.py
+++ b/django/contrib/sessions/middleware.py
@@ -39,6 +39,7 @@ class SessionMiddleware(MiddlewareMixin):
settings.SESSION_COOKIE_NAME,
path=settings.SESSION_COOKIE_PATH,
domain=settings.SESSION_COOKIE_DOMAIN,
+ samesite=settings.SESSION_COOKIE_SAMESITE,
)
else:
if accessed:
diff --git a/django/http/response.py b/django/http/response.py
index f7d248e933..5a693b1786 100644
--- a/django/http/response.py
+++ b/django/http/response.py
@@ -210,13 +210,13 @@ class HttpResponseBase:
value = signing.get_cookie_signer(salt=key + salt).sign(value)
return self.set_cookie(key, value, **kwargs)
- def delete_cookie(self, key, path='/', domain=None):
+ def delete_cookie(self, key, path='/', domain=None, samesite=None):
# Most browsers ignore the Set-Cookie header if the cookie name starts
# with __Host- or __Secure- and the cookie doesn't use the secure flag.
secure = key.startswith(('__Secure-', '__Host-'))
self.set_cookie(
key, max_age=0, path=path, domain=domain, secure=secure,
- expires='Thu, 01 Jan 1970 00:00:00 GMT',
+ expires='Thu, 01 Jan 1970 00:00:00 GMT', samesite=samesite,
)
# Common methods used by subclasses
diff --git a/docs/ref/request-response.txt b/docs/ref/request-response.txt
index 08eaf62ca4..c0fb0133f3 100644
--- a/docs/ref/request-response.txt
+++ b/docs/ref/request-response.txt
@@ -841,7 +841,7 @@ Methods
you will need to remember to pass it to the corresponding
:meth:`HttpRequest.get_signed_cookie` call.
-.. method:: HttpResponse.delete_cookie(key, path='/', domain=None)
+.. method:: HttpResponse.delete_cookie(key, path='/', domain=None, samesite=None)
Deletes the cookie with the given key. Fails silently if the key doesn't
exist.
@@ -850,6 +850,10 @@ Methods
values you used in ``set_cookie()`` -- otherwise the cookie may not be
deleted.
+ .. versionchanged:: 2.2.15
+
+ The ``samesite`` argument was added.
+
.. method:: HttpResponse.close()
This method is called at the end of the request directly by the WSGI
diff --git a/docs/releases/2.2.15.txt b/docs/releases/2.2.15.txt
new file mode 100644
index 0000000000..df26962029
--- /dev/null
+++ b/docs/releases/2.2.15.txt
@@ -0,0 +1,13 @@
+===========================
+Django 2.2.15 release notes
+===========================
+
+*Expected August 3, 2020*
+
+Django 2.2.15 fixes a bug in 2.2.14.
+
+Bugfixes
+========
+
+* Allowed setting the ``SameSite`` cookie flag in
+ :meth:`.HttpResponse.delete_cookie` (:ticket:`31790`).
diff --git a/docs/releases/index.txt b/docs/releases/index.txt
index 2a355d3d94..3cb0089457 100644
--- a/docs/releases/index.txt
+++ b/docs/releases/index.txt
@@ -25,6 +25,7 @@ versions of the documentation contain the release notes for any later releases.
.. toctree::
:maxdepth: 1
+ 2.2.15
2.2.14
2.2.13
2.2.12
diff --git a/tests/messages_tests/test_cookie.py b/tests/messages_tests/test_cookie.py
index 211d33f04c..7456e03a70 100644
--- a/tests/messages_tests/test_cookie.py
+++ b/tests/messages_tests/test_cookie.py
@@ -1,5 +1,6 @@
import json
+from django.conf import settings
from django.contrib.messages import constants
from django.contrib.messages.storage.base import Message
from django.contrib.messages.storage.cookie import (
@@ -85,6 +86,10 @@ class CookieTests(BaseTests, SimpleTestCase):
self.assertEqual(response.cookies['messages'].value, '')
self.assertEqual(response.cookies['messages']['domain'], '.example.com')
self.assertEqual(response.cookies['messages']['expires'], 'Thu, 01 Jan 1970 00:00:00 GMT')
+ self.assertEqual(
+ response.cookies['messages']['samesite'],
+ settings.SESSION_COOKIE_SAMESITE,
+ )
def test_get_bad_cookie(self):
request = self.get_request()
diff --git a/tests/responses/test_cookie.py b/tests/responses/test_cookie.py
index a5092c3bbf..68927a4ee2 100644
--- a/tests/responses/test_cookie.py
+++ b/tests/responses/test_cookie.py
@@ -102,6 +102,7 @@ class DeleteCookieTests(SimpleTestCase):
self.assertEqual(cookie['path'], '/')
self.assertEqual(cookie['secure'], '')
self.assertEqual(cookie['domain'], '')
+ self.assertEqual(cookie['samesite'], '')
def test_delete_cookie_secure_prefix(self):
"""
@@ -115,3 +116,8 @@ class DeleteCookieTests(SimpleTestCase):
cookie_name = '__%s-c' % prefix
response.delete_cookie(cookie_name)
self.assertEqual(response.cookies[cookie_name]['secure'], True)
+
+ def test_delete_cookie_samesite(self):
+ response = HttpResponse()
+ response.delete_cookie('c', samesite='lax')
+ self.assertEqual(response.cookies['c']['samesite'], 'lax')
diff --git a/tests/sessions_tests/tests.py b/tests/sessions_tests/tests.py
index 733f5adb1d..901995fa88 100644
--- a/tests/sessions_tests/tests.py
+++ b/tests/sessions_tests/tests.py
@@ -743,8 +743,9 @@ class SessionMiddlewareTests(TestCase):
# Set-Cookie: sessionid=; expires=Thu, 01 Jan 1970 00:00:00 GMT; Max-Age=0; Path=/
self.assertEqual(
'Set-Cookie: {}=""; expires=Thu, 01 Jan 1970 00:00:00 GMT; '
- 'Max-Age=0; Path=/'.format(
+ 'Max-Age=0; Path=/; SameSite={}'.format(
settings.SESSION_COOKIE_NAME,
+ settings.SESSION_COOKIE_SAMESITE,
),
str(response.cookies[settings.SESSION_COOKIE_NAME])
)
@@ -772,8 +773,9 @@ class SessionMiddlewareTests(TestCase):
# Path=/example/
self.assertEqual(
'Set-Cookie: {}=""; Domain=.example.local; expires=Thu, '
- '01 Jan 1970 00:00:00 GMT; Max-Age=0; Path=/example/'.format(
+ '01 Jan 1970 00:00:00 GMT; Max-Age=0; Path=/example/; SameSite={}'.format(
settings.SESSION_COOKIE_NAME,
+ settings.SESSION_COOKIE_SAMESITE,
),
str(response.cookies[settings.SESSION_COOKIE_NAME])
)