Skip to content

Commit b4198a8

Browse files
[3.13] gh-160300: Reject cookies with a negative version in http.cookiejar (GH-160301) (#160647)
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 de84a64 commit b4198a8

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
@@ -1114,6 +1120,9 @@ def return_ok(self, cookie, request):
11141120
return True
11151121

11161122
def return_ok_version(self, cookie, request):
1123+
if cookie.version < 0:
1124+
_debug(" negative version attribute")
1125+
return False
11171126
if cookie.version > 0 and not self.rfc2965:
11181127
_debug(" RFC 2965 cookies are switched off")
11191128
return False
@@ -1502,6 +1511,8 @@ def _cookie_from_cookie_tuple(self, tup, request):
15021511
version = int(version)
15031512
except ValueError:
15041513
return None # invalid version, ignore cookie
1514+
if version < 0:
1515+
return None # invalid version, ignore cookie
15051516
secure = standard.get("secure", False)
15061517
# (discard is also set if expires is Absent)
15071518
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
@@ -936,10 +936,37 @@ def test_wrong_domain(self):
936936

937937
# XXX far from complete
938938
c = CookieJar()
939-
interact_2965(c, "http://www.nasty.com/",
940-
'foo=bar; domain=friendly.org; Version="1"')
939+
interact_2965(c, "http://www.example.com/",
940+
'foo=bar; domain=python.org; Version="1"')
941941
self.assertEqual(len(c), 0)
942942

943+
def test_negative_version(self):
944+
# A negative version is neither Netscape (0) nor RFC 2965 (> 0), so
945+
# such cookies must be neither set nor returned.
946+
for rfc2965 in False, True:
947+
for interact in interact_netscape, interact_2965:
948+
with self.subTest(rfc2965=rfc2965, interact=interact.__name__):
949+
c = CookieJar(DefaultCookiePolicy(rfc2965=rfc2965))
950+
interact(c, "http://www.example.com/",
951+
'foo=bar; domain=python.org; Version=-1')
952+
self.assertEqual(len(c), 0)
953+
interact(c, "http://www.example.com/", 'foo=bar; Version=-1')
954+
self.assertEqual(len(c), 0)
955+
956+
# Such a header is discarded before the policy is consulted.
957+
c = CookieJar()
958+
req = urllib.request.Request("http://www.example.com/")
959+
res = FakeResponse(["Set-Cookie: foo=bar; Version=-1"],
960+
"http://www.example.com/")
961+
self.assertEqual(c.make_cookies(res, req), [])
962+
963+
# Not set from a response, for example loaded from an LWP cookie file.
964+
c = CookieJar()
965+
c.set_cookie(Cookie(-1, "foo", "bar", None, False,
966+
".python.org", True, True, "/", True,
967+
False, None, True, None, None, {}))
968+
self.assertEqual(interact_netscape(c, "http://www.python.org/"), "")
969+
943970
def test_strict_domain(self):
944971
# Cookies whose domain is a country-code tld like .co.uk should
945972
# not be set if CookiePolicy.strict_domain is true.
@@ -1439,6 +1466,7 @@ def cookiejar_from_cookie_headers(headers):
14391466
["Set-Cookie: b=foo; max-age=oops"],
14401467
# bad version
14411468
["Set-Cookie: b=foo; version=spam"],
1469+
["Set-Cookie: b=foo; version=-1"],
14421470
["Set-Cookie:; Expires=%s" % future],
14431471
]:
14441472
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)