Skip to content

Commit 9c86939

Browse files
gpsheadmiss-islington
authored andcommitted
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 f9d2cd0 commit 9c86939

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
@@ -909,10 +909,37 @@ def test_wrong_domain(self):
909909

910910
# XXX far from complete
911911
c = CookieJar()
912-
interact_2965(c, "http://www.nasty.com/",
913-
'foo=bar; domain=friendly.org; Version="1"')
912+
interact_2965(c, "http://www.example.com/",
913+
'foo=bar; domain=python.org; Version="1"')
914914
self.assertEqual(len(c), 0)
915915

916+
def test_negative_version(self):
917+
# A negative version is neither Netscape (0) nor RFC 2965 (> 0), so
918+
# such cookies must be neither set nor returned.
919+
for rfc2965 in False, True:
920+
for interact in interact_netscape, interact_2965:
921+
with self.subTest(rfc2965=rfc2965, interact=interact.__name__):
922+
c = CookieJar(DefaultCookiePolicy(rfc2965=rfc2965))
923+
interact(c, "http://www.example.com/",
924+
'foo=bar; domain=python.org; Version=-1')
925+
self.assertEqual(len(c), 0)
926+
interact(c, "http://www.example.com/", 'foo=bar; Version=-1')
927+
self.assertEqual(len(c), 0)
928+
929+
# Such a header is discarded before the policy is consulted.
930+
c = CookieJar()
931+
req = urllib.request.Request("http://www.example.com/")
932+
res = FakeResponse(["Set-Cookie: foo=bar; Version=-1"],
933+
"http://www.example.com/")
934+
self.assertEqual(c.make_cookies(res, req), [])
935+
936+
# Not set from a response, for example loaded from an LWP cookie file.
937+
c = CookieJar()
938+
c.set_cookie(Cookie(-1, "foo", "bar", None, False,
939+
".python.org", True, True, "/", True,
940+
False, None, True, None, None, {}))
941+
self.assertEqual(interact_netscape(c, "http://www.python.org/"), "")
942+
916943
def test_strict_domain(self):
917944
# Cookies whose domain is a country-code tld like .co.uk should
918945
# not be set if CookiePolicy.strict_domain is true.
@@ -1412,6 +1439,7 @@ def cookiejar_from_cookie_headers(headers):
14121439
["Set-Cookie: b=foo; max-age=oops"],
14131440
# bad version
14141441
["Set-Cookie: b=foo; version=spam"],
1442+
["Set-Cookie: b=foo; version=-1"],
14151443
["Set-Cookie:; Expires=%s" % future],
14161444
]:
14171445
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)