Test 1
fail to passdelete cookie samesite (responses.cookie.DeleteCookieTests)
Django: delete_cookie() Fails to Preserve SameSite Attribute
django__django-13195 · cardboard
You are working in the django/django repository at commit 156a2138db20abc89933121e4ff2ee2ce56a173a (Django 3.2 development branch).
HttpResponse.delete_cookie() does not accept or forward a samesite argument to the underlying set_cookie() call. This causes a silent incompatibility in modern browsers:
When a browser stores a cookie with a SameSite attribute (e.g. SameSite=None; Secure or SameSite=Lax), the deletion Set-Cookie header must repeat that same SameSite attribute, or the browser will treat the deletion header as referring to a different cookie and silently ignore it.
As a result, calling response.delete_cookie("sessionid") when the session cookie was originally set with SESSION_COOKIE_SAMESITE = "None" does not delete the cookie in Chrome 80+ or Firefox 79+ — the session persists even though the application believes it was deleted.
The same silent failure affects:
response.delete_cookie() at session end.messages cookie storage backend when it clears its cookie.from django.http import HttpResponse
response = HttpResponse()
# Simulate the browser storing: Set-Cookie: token=abc; SameSite=None; Secure
# Later, the app tries to delete the cookie:
response.delete_cookie("token")
print(response.cookies["token"]["samesite"]) # '' — SameSite missing from deletion headerThe Set-Cookie header for the deletion is:
Set-Cookie: token=""; expires=Thu, 01 Jan 1970 00:00:00 GMT; Max-Age=0; Path=/A compliant deletion for a SameSite=None cookie must be:
Set-Cookie: token=""; expires=Thu, 01 Jan 1970 00:00:00 GMT; Max-Age=0; Path=/; SameSite=None; SecureHttpResponse.delete_cookie() — new samesite parameterExtend the method signature in django/http/response.py:
def delete_cookie(self, key, path='/', domain=None, samesite='Lax'):Behaviour rules:
samesite is provided (non-empty string), delete_cookie() must pass it through to set_cookie() as the samesite keyword argument.samesite is 'None' (case-insensitive), delete_cookie() must also pass secure=True to set_cookie(), because browsers reject SameSite=None cookies that are not Secure.samesite parameter must be passed with the same case-insensitivity behaviour that set_cookie() already uses (it normalises to title-case internally, so passing 'none' or 'NONE' is fine — your code just needs to detect the value for the secure flag before forwarding it).django/contrib/sessions/middleware.pySessionMiddleware.process_response() already reads settings.SESSION_COOKIE_SAMESITE. When it calls response.delete_cookie(), it must now pass samesite=settings.SESSION_COOKIE_SAMESITE so the deletion header matches the original cookie.
django/contrib/messages/storage/cookie.pyCookieStorage._delete_cookies() (or equivalent) calls response.delete_cookie(). It must pass samesite=self.samesite (the configured value for the messages cookie, read from settings.MESSAGE_COOKIE_SAMESITE) so the deletion header matches the original cookie.
| File | What to change |
|---|---|
| django/http/response.py | Add samesite param to delete_cookie(); wire it to set_cookie() |
| django/contrib/sessions/middleware.py | Pass samesite=settings.SESSION_COOKIE_SAMESITE to delete_cookie() |
| django/contrib/messages/storage/cookie.py | Pass samesite=self.samesite to delete_cookie() |
Do not change any test files — the grader applies its own test patch.
samesite forwardingfrom django.http import HttpResponse
r = HttpResponse()
r.delete_cookie("mycookie", samesite="Lax")
print(r.cookies["mycookie"]["samesite"]) # "Lax"
print(r.cookies["mycookie"]["secure"]) # '' (not forced secure for Lax)SameSite=None forces Securefrom django.http import HttpResponse
r = HttpResponse()
r.delete_cookie("mycookie", samesite="None")
print(r.cookies["mycookie"]["samesite"]) # "None"
print(r.cookies["mycookie"]["secure"]) # True (forced because SameSite=None)from django.http import HttpResponse
r = HttpResponse()
r.delete_cookie("mycookie")
# No explicit samesite in the output header — existing callers not brokenGiven SESSION_COOKIE_SAMESITE = "None" in settings:
# After session.flush(), the middleware calls:
response.delete_cookie(
settings.SESSION_COOKIE_NAME,
path=settings.SESSION_COOKIE_PATH,
domain=settings.SESSION_COOKIE_DOMAIN,
samesite=settings.SESSION_COOKIE_SAMESITE,
)
# Resulting Set-Cookie must contain: SameSite=None; Securetests/ directories or */tests.py). The hidden grader provides its own test patch.response.py, middleware.py, or cookie.py.set_cookie() method's existing signature or semantics.set_cookie() already validates samesite and raises ValueError for invalid values; you do not need to add your own validation in delete_cookie().Your submission is accepted when all 5 FAIL_TO_PASS tests pass and all 24 PASS_TO_PASS regression tests continue to pass. Leaderboard ranking additionally considers total tokens used, estimated cost, and wall-clock time.
Container
not started
Visible tests
29
Hidden tests
0
Last run
Not run
Test 1
fail to passdelete cookie samesite (responses.cookie.DeleteCookieTests)
Test 2
fail to passdelete cookie secure samesite none (responses.cookie.DeleteCookieTests)
Test 3
fail to passsession delete on end (sessions tests.tests.SessionMiddlewareTests)
Test 4
fail to passsession delete on end with custom domain and path (sessions tests.tests.SessionMiddlewareTests)
Test 5
fail to passcookie setings (messages tests.cookie.CookieTests)
Test 6
pass to passdefault (responses.cookie.DeleteCookieTests)
Test 7
pass to passdelete cookie secure prefix (responses.cookie.DeleteCookieTests)
Test 8
pass to passhttponly cookie (responses.cookie.SetCookieTests)
Test 9
pass to passinvalid samesite (responses.cookie.SetCookieTests)
Test 10
pass to passsamesite (responses.cookie.SetCookieTests)
Test 11
pass to passclear (sessions tests.tests.CookieSessionTests)
Test 12
pass to passcustom expiry datetime (sessions tests.tests.CookieSessionTests)
Test 13
pass to passcustom expiry reset (sessions tests.tests.CookieSessionTests)
Test 14
pass to passcycle (sessions tests.tests.CookieSessionTests)
Test 15
pass to passdecode (sessions tests.tests.CookieSessionTests)
Test 16
pass to passdecode legacy (sessions tests.tests.CookieSessionTests)
Test 17
pass to passempty session saved (sessions tests.tests.SessionMiddlewareTests)
Test 18
pass to passflush empty without session cookie doesnt set cookie (sessions tests.tests.SessionMiddlewareTests)
Test 19
pass to passhttponly session cookie (sessions tests.tests.SessionMiddlewareTests)
Test 20
pass to passno httponly session cookie (sessions tests.tests.SessionMiddlewareTests)
Test 21
pass to passsamesite session cookie (sessions tests.tests.SessionMiddlewareTests)
Test 22
pass to passsecure session cookie (sessions tests.tests.SessionMiddlewareTests)
Test 23
pass to passsession save on 500 (sessions tests.tests.SessionMiddlewareTests)
Test 24
pass to passsession update error redirect (sessions tests.tests.SessionMiddlewareTests)
Test 25
pass to passadd (messages tests.cookie.CookieTests)
Test 26
pass to passadd lazy translation (messages tests.cookie.CookieTests)
Test 27
pass to passfull request response cycle (messages tests.cookie.CookieTests)
Test 28
pass to passget (messages tests.cookie.CookieTests)
Test 29
pass to passmax cookie length (messages tests.cookie.CookieTests)
README.md
django/django