Skip to content

Commit 673da87

Browse files
[3.12] gh-160300: Reject cookies with a negative version in http.cookiejar (GH-160301) (#160648)
gh-160300: Reject cookies with a negative version in http.cookiejar (GH-160301) DefaultCookiePolicy only applied its domain checks to cookies with version 0 or a positive version. ANT-2026-TA36I7V7 (cherry picked from commit d59d968) Co-authored-by: Gregory P. Smith <68491+gpshead@users.noreply.github.com>
1 parent 5cf3260 commit 673da87

3 files changed

Lines changed: 44 additions & 2 deletions

File tree

‎Lib/http/cookiejar.py‎

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -972,6 +972,12 @@ def set_ok_version(self, cookie, request):
972972
_debug(" Set-Cookie2 without version attribute (%s=%s)",
973973
cookie.name, cookie.value)
974974
return False
975+
if cookie.version < 0:
976+
# Neither the Netscape (version 0) nor the RFC 2965 (version > 0)
977+
# rules would apply, so the domain checks would all be skipped.
978+
_debug(" negative version attribute (%s=%s)",
979+
cookie.name, cookie.value)
980+
return False
975981
if cookie.version > 0 and not self.rfc2965:
976982
_debug(" RFC 2965 cookies are switched off")
977983
return False
@@ -1112,6 +1118,9 @@ def return_ok(self, cookie, request):
11121118
return True
11131119

11141120
def return_ok_version(self, cookie, request):
1121+
if cookie.version < 0:
1122+
_debug(" negative version attribute")
1123+
return False
11151124
if cookie.version > 0 and not self.rfc2965:
11161125
_debug(" RFC 2965 cookies are switched off")
11171126
return False
@@ -1500,6 +1509,8 @@ def _cookie_from_cookie_tuple(self, tup, request):
15001509
version = int(version)
15011510
except ValueError:
15021511
return None # invalid version, ignore cookie
1512+
if version < 0:
1513+
return None # invalid version, ignore cookie
15031514
secure = standard.get("secure", False)
15041515
# (discard is also set if expires is Absent)
15051516
discard = standard.get("discard", False)

‎Lib/test/test_http_cookiejar.py‎

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -907,10 +907,37 @@ def test_wrong_domain(self):
907907

908908
# XXX far from complete
909909
c = CookieJar()
910-
interact_2965(c, "http://www.nasty.com/",
911-
'foo=bar; domain=friendly.org; Version="1"')
910+
interact_2965(c, "http://www.example.com/",
911+
'foo=bar; domain=python.org; Version="1"')
912912
self.assertEqual(len(c), 0)
913913

914+
def test_negative_version(self):
915+
# A negative version is neither Netscape (0) nor RFC 2965 (> 0), so
916+
# such cookies must be neither set nor returned.
917+
for rfc2965 in False, True:
918+
for interact in interact_netscape, interact_2965:
919+
with self.subTest(rfc2965=rfc2965, interact=interact.__name__):
920+
c = CookieJar(DefaultCookiePolicy(rfc2965=rfc2965))
921+
interact(c, "http://www.example.com/",
922+
'foo=bar; domain=python.org; Version=-1')
923+
self.assertEqual(len(c), 0)
924+
interact(c, "http://www.example.com/", 'foo=bar; Version=-1')
925+
self.assertEqual(len(c), 0)
926+
927+
# Such a header is discarded before the policy is consulted.
928+
c = CookieJar()
929+
req = urllib.request.Request("http://www.example.com/")
930+
res = FakeResponse(["Set-Cookie: foo=bar; Version=-1"],
931+
"http://www.example.com/")
932+
self.assertEqual(c.make_cookies(res, req), [])
933+
934+
# Not set from a response, for example loaded from an LWP cookie file.
935+
c = CookieJar()
936+
c.set_cookie(Cookie(-1, "foo", "bar", None, False,
937+
".python.org", True, True, "/", True,
938+
False, None, True, None, None, {}))
939+
self.assertEqual(interact_netscape(c, "http://www.python.org/"), "")
940+
914941
def test_strict_domain(self):
915942
# Cookies whose domain is a country-code tld like .co.uk should
916943
# not be set if CookiePolicy.strict_domain is true.
@@ -1410,6 +1437,7 @@ def cookiejar_from_cookie_headers(headers):
14101437
["Set-Cookie: b=foo; max-age=oops"],
14111438
# bad version
14121439
["Set-Cookie: b=foo; version=spam"],
1440+
["Set-Cookie: b=foo; version=-1"],
14131441
["Set-Cookie:; Expires=%s" % future],
14141442
]:
14151443
c = cookiejar_from_cookie_headers(headers)
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
Fix :class:`http.cookiejar.DefaultCookiePolicy` accepting and returning
2+
cookies with a negative ``Version`` attribute without checking their domain
3+
against the request host. Such cookies are now ignored.

0 commit comments

Comments
 (0)