diff --git a/django/http/response.py b/django/http/response.py index 76d731d53fd..b6f29cc0563 100644 --- a/django/http/response.py +++ b/django/http/response.py @@ -205,8 +205,13 @@ class HttpResponseBase: return self.set_cookie(key, value, **kwargs) def delete_cookie(self, key, path='/', domain=None): - self.set_cookie(key, max_age=0, path=path, domain=domain, - expires='Thu, 01 Jan 1970 00:00:00 GMT') + # 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', + ) # Common methods used by subclasses diff --git a/tests/responses/test_cookie.py b/tests/responses/test_cookie.py index cbd65926c04..148963fa596 100644 --- a/tests/responses/test_cookie.py +++ b/tests/responses/test_cookie.py @@ -91,3 +91,16 @@ class DeleteCookieTests(SimpleTestCase): self.assertEqual(cookie['path'], '/') self.assertEqual(cookie['secure'], '') self.assertEqual(cookie['domain'], '') + + def test_delete_cookie_secure_prefix(self): + """ + delete_cookie() sets the secure flag if the cookie name starts with + __Host- or __Secure- (without that, browsers ignore cookies with those + prefixes). + """ + response = HttpResponse() + for prefix in ('Secure', 'Host'): + with self.subTest(prefix=prefix): + cookie_name = '__%s-c' % prefix + response.delete_cookie(cookie_name) + self.assertEqual(response.cookies[cookie_name]['secure'], True)