diff --git a/Lib/http/cookiejar.py b/Lib/http/cookiejar.py index 13e5b104a81ea2b..5fd61b683e7e6ab 100644 --- a/Lib/http/cookiejar.py +++ b/Lib/http/cookiejar.py @@ -578,8 +578,9 @@ def domain_match(A, B): if not is_HDN(A): return False i = A.rfind(B) - if i == -1 or i == 0: - # A does not have form NB, or N is the empty string + if i == -1 or i == 0 or i + len(B) != len(A): + # A does not have form NB, N is the empty string, or B is not a + # suffix of A (so A only contains B as an interior substring) return False if not B.startswith("."): return False diff --git a/Lib/test/test_http_cookiejar.py b/Lib/test/test_http_cookiejar.py index 04cb440cd4ccf66..b722ee528917d52 100644 --- a/Lib/test/test_http_cookiejar.py +++ b/Lib/test/test_http_cookiejar.py @@ -888,6 +888,9 @@ def test_domain_match(self): self.assertFalse(domain_match("blah.blah", "")) self.assertFalse(domain_match("", ".rhubarb.rhubarb")) self.assertTrue(domain_match("", "")) + # B must be a suffix of A, not just an interior substring + self.assertFalse(domain_match("www.acme.com.evil.org", ".acme.com")) + self.assertFalse(domain_match("a.b.c.com.example.net", ".c.com")) self.assertTrue(user_domain_match("acme.com", "acme.com")) self.assertFalse(user_domain_match("acme.com", ".acme.com")) diff --git a/Misc/NEWS.d/next/Library/2026-05-27-11-20-00.gh-issue-150522.Qd7Rb3.rst b/Misc/NEWS.d/next/Library/2026-05-27-11-20-00.gh-issue-150522.Qd7Rb3.rst new file mode 100644 index 000000000000000..6af988a4b742701 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2026-05-27-11-20-00.gh-issue-150522.Qd7Rb3.rst @@ -0,0 +1,3 @@ +:func:`http.cookiejar.domain_match` now requires the second domain to be a +suffix of the first instead of merely an interior substring, so a host such +as ``www.example.com.evil`` no longer domain-matches ``.example.com``.