diff --git a/Lib/http/cookiejar.py b/Lib/http/cookiejar.py index ee433c0f78f..136a1f16ffe 100644 --- a/Lib/http/cookiejar.py +++ b/Lib/http/cookiejar.py @@ -1043,12 +1043,13 @@ class DefaultCookiePolicy(CookiePolicy): else: undotted_domain = domain embedded_dots = (undotted_domain.find(".") >= 0) - if not embedded_dots and domain != ".local": + if not embedded_dots and not erhn.endswith(".local"): _debug(" non-local domain %s contains no embedded dot", domain) return False if cookie.version == 0: - if (not erhn.endswith(domain) and + if (not (erhn.endswith(domain) or + erhn.endswith(f"{undotted_domain}.local")) and (not erhn.startswith(".") and not ("."+erhn).endswith(domain))): _debug(" effective request-host %s (even with added " diff --git a/Lib/test/test_http_cookiejar.py b/Lib/test/test_http_cookiejar.py index 9450104d0b9..126ce4fc83f 100644 --- a/Lib/test/test_http_cookiejar.py +++ b/Lib/test/test_http_cookiejar.py @@ -920,6 +920,48 @@ class CookieTests(unittest.TestCase): ## self.assertEqual(len(c), 2) self.assertEqual(len(c), 4) + def test_localhost_domain(self): + c = CookieJar() + + interact_netscape(c, "http://localhost", "foo=bar; domain=localhost;") + + self.assertEqual(len(c), 1) + + def test_localhost_domain_contents(self): + c = CookieJar() + + interact_netscape(c, "http://localhost", "foo=bar; domain=localhost;") + + self.assertEqual(c._cookies[".localhost"]["/"]["foo"].value, "bar") + + def test_localhost_domain_contents_2(self): + c = CookieJar() + + interact_netscape(c, "http://localhost", "foo=bar;") + + self.assertEqual(c._cookies["localhost.local"]["/"]["foo"].value, "bar") + + def test_evil_nonlocal_domain(self): + c = CookieJar() + + interact_netscape(c, "http://evil.com", "foo=bar; domain=.localhost") + + self.assertEqual(len(c), 0) + + def test_evil_local_domain(self): + c = CookieJar() + + interact_netscape(c, "http://localhost", "foo=bar; domain=.evil.com") + + self.assertEqual(len(c), 0) + + def test_evil_local_domain_2(self): + c = CookieJar() + + interact_netscape(c, "http://localhost", "foo=bar; domain=.someother.local") + + self.assertEqual(len(c), 0) + def test_two_component_domain_rfc2965(self): pol = DefaultCookiePolicy(rfc2965=True) c = CookieJar(pol) diff --git a/Misc/NEWS.d/next/Library/2021-12-14-21-19-04.bpo-46075.KDtcU-.rst b/Misc/NEWS.d/next/Library/2021-12-14-21-19-04.bpo-46075.KDtcU-.rst new file mode 100644 index 00000000000..e01319300be --- /dev/null +++ b/Misc/NEWS.d/next/Library/2021-12-14-21-19-04.bpo-46075.KDtcU-.rst @@ -0,0 +1 @@ +``CookieJar`` with ``DefaultCookiePolicy`` now can process cookies from localhost with domain=localhost explicitly specified in Set-Cookie header.