Skip to content

Commit 97c7d78

Browse files
bpo-35647: Fix path check in cookiejar (GH-11436)
* Refactor cookie path check as per RFC 6265 * Add tests for prefix match of path * Add news entry * Fix set_ok_path and refactor tests * Use slice for last letter (cherry picked from commit 0e1f1f0) Co-authored-by: Xtreak <tir.karthi@gmail.com>
1 parent 87f5255 commit 97c7d78

File tree

3 files changed

+36
-5
lines changed

3 files changed

+36
-5
lines changed

Lib/http/cookiejar.py

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -990,7 +990,7 @@ def set_ok_path(self, cookie, request):
990990
req_path = request_path(request)
991991
if ((cookie.version > 0 or
992992
(cookie.version == 0 and self.strict_ns_set_path)) and
993-
not req_path.startswith(cookie.path)):
993+
not self.path_return_ok(cookie.path, request)):
994994
_debug(" path attribute %s is not a prefix of request "
995995
"path %s", cookie.path, req_path)
996996
return False
@@ -1197,11 +1197,15 @@ def domain_return_ok(self, domain, request):
11971197
def path_return_ok(self, path, request):
11981198
_debug("- checking cookie path=%s", path)
11991199
req_path = request_path(request)
1200-
if not req_path.startswith(path):
1201-
_debug(" %s does not path-match %s", req_path, path)
1202-
return False
1203-
return True
1200+
pathlen = len(path)
1201+
if req_path == path:
1202+
return True
1203+
elif (req_path.startswith(path) and
1204+
(path.endswith("/") or req_path[pathlen:pathlen+1] == "/")):
1205+
return True
12041206

1207+
_debug(" %s does not path-match %s", req_path, path)
1208+
return False
12051209

12061210
def vals_sorted_by_key(adict):
12071211
keys = sorted(adict.keys())

Lib/test/test_http_cookiejar.py

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -695,6 +695,30 @@ def test_request_path(self):
695695
req = urllib.request.Request("http://www.example.com")
696696
self.assertEqual(request_path(req), "/")
697697

698+
def test_path_prefix_match(self):
699+
pol = DefaultCookiePolicy()
700+
strict_ns_path_pol = DefaultCookiePolicy(strict_ns_set_path=True)
701+
702+
c = CookieJar(pol)
703+
base_url = "http://bar.com"
704+
interact_netscape(c, base_url, 'spam=eggs; Path=/foo')
705+
cookie = c._cookies['bar.com']['/foo']['spam']
706+
707+
for path, ok in [('/foo', True),
708+
('/foo/', True),
709+
('/foo/bar', True),
710+
('/', False),
711+
('/foobad/foo', False)]:
712+
url = f'{base_url}{path}'
713+
req = urllib.request.Request(url)
714+
h = interact_netscape(c, url)
715+
if ok:
716+
self.assertIn('spam=eggs', h, f"cookie not set for {path}")
717+
self.assertTrue(strict_ns_path_pol.set_ok_path(cookie, req))
718+
else:
719+
self.assertNotIn('spam=eggs', h, f"cookie set for {path}")
720+
self.assertFalse(strict_ns_path_pol.set_ok_path(cookie, req))
721+
698722
def test_request_port(self):
699723
req = urllib.request.Request("http://www.acme.com:1234/",
700724
headers={"Host": "www.acme.com:4321"})
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
Don't set cookie for a request when the request path is a prefix match of
2+
the cookie's path attribute but doesn't end with "/". Patch by Karthikeyan
3+
Singaravelan.

0 commit comments

Comments
 (0)