Skip to content

Commit d59d968

Browse files
authored
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
1 parent 9a23541 commit d59d968

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
@@ -974,6 +974,12 @@ def set_ok_version(self, cookie, request):
974974
_debug(" Set-Cookie2 without version attribute (%s=%s)",
975975
cookie.name, cookie.value)
976976
return False
977+
if cookie.version < 0:
978+
# Neither the Netscape (version 0) nor the RFC 2965 (version > 0)
979+
# rules would apply, so the domain checks would all be skipped.
980+
_debug(" negative version attribute (%s=%s)",
981+
cookie.name, cookie.value)
982+
return False
977983
if cookie.version > 0 and not self.rfc2965:
978984
_debug(" RFC 2965 cookies are switched off")
979985
return False
@@ -1117,6 +1123,9 @@ def return_ok(self, cookie, request):
11171123
return True
11181124

11191125
def return_ok_version(self, cookie, request):
1126+
if cookie.version < 0:
1127+
_debug(" negative version attribute")
1128+
return False
11201129
if cookie.version > 0 and not self.rfc2965:
11211130
_debug(" RFC 2965 cookies are switched off")
11221131
return False
@@ -1505,6 +1514,8 @@ def _cookie_from_cookie_tuple(self, tup, request):
15051514
version = int(version)
15061515
except ValueError:
15071516
return None # invalid version, ignore cookie
1517+
if version < 0:
1518+
return None # invalid version, ignore cookie
15081519
secure = standard.get("secure", False)
15091520
# (discard is also set if expires is Absent)
15101521
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
@@ -943,10 +943,37 @@ def test_wrong_domain(self):
943943

944944
# XXX far from complete
945945
c = CookieJar()
946-
interact_2965(c, "http://www.nasty.com/",
947-
'foo=bar; domain=friendly.org; Version="1"')
946+
interact_2965(c, "http://www.example.com/",
947+
'foo=bar; domain=python.org; Version="1"')
948948
self.assertEqual(len(c), 0)
949949

950+
def test_negative_version(self):
951+
# A negative version is neither Netscape (0) nor RFC 2965 (> 0), so
952+
# such cookies must be neither set nor returned.
953+
for rfc2965 in False, True:
954+
for interact in interact_netscape, interact_2965:
955+
with self.subTest(rfc2965=rfc2965, interact=interact.__name__):
956+
c = CookieJar(DefaultCookiePolicy(rfc2965=rfc2965))
957+
interact(c, "http://www.example.com/",
958+
'foo=bar; domain=python.org; Version=-1')
959+
self.assertEqual(len(c), 0)
960+
interact(c, "http://www.example.com/", 'foo=bar; Version=-1')
961+
self.assertEqual(len(c), 0)
962+
963+
# Such a header is discarded before the policy is consulted.
964+
c = CookieJar()
965+
req = urllib.request.Request("http://www.example.com/")
966+
res = FakeResponse(["Set-Cookie: foo=bar; Version=-1"],
967+
"http://www.example.com/")
968+
self.assertEqual(c.make_cookies(res, req), [])
969+
970+
# Not set from a response, for example loaded from an LWP cookie file.
971+
c = CookieJar()
972+
c.set_cookie(Cookie(-1, "foo", "bar", None, False,
973+
".python.org", True, True, "/", True,
974+
False, None, True, None, None, {}))
975+
self.assertEqual(interact_netscape(c, "http://www.python.org/"), "")
976+
950977
def test_strict_domain(self):
951978
# Cookies whose domain is a country-code tld like .co.uk should
952979
# not be set if CookiePolicy.strict_domain is true.
@@ -1446,6 +1473,7 @@ def cookiejar_from_cookie_headers(headers):
14461473
["Set-Cookie: b=foo; max-age=oops"],
14471474
# bad version
14481475
["Set-Cookie: b=foo; version=spam"],
1476+
["Set-Cookie: b=foo; version=-1"],
14491477
["Set-Cookie:; Expires=%s" % future],
14501478
]:
14511479
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)