From 77e9c16dca38f9b07e9065fa15e9cab11ce3669d Mon Sep 17 00:00:00 2001 From: xtreak Date: Thu, 27 Dec 2018 16:22:55 +0530 Subject: [PATCH 1/5] Refactor cookie path check as per RFC 6265 --- Lib/http/cookiejar.py | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/Lib/http/cookiejar.py b/Lib/http/cookiejar.py index 0ba8200f325a62..3467dc06210e0f 100644 --- a/Lib/http/cookiejar.py +++ b/Lib/http/cookiejar.py @@ -1190,11 +1190,14 @@ def domain_return_ok(self, domain, request): def path_return_ok(self, path, request): _debug("- checking cookie path=%s", path) req_path = request_path(request) - if not req_path.startswith(path): - _debug(" %s does not path-match %s", req_path, path) - return False - return True + if req_path == path: + return True + elif (req_path.startswith(path) and + (path.endswith("/") or req_path[len(path)] == "/")): + return True + _debug(" %s does not path-match %s", req_path, path) + return False def vals_sorted_by_key(adict): keys = sorted(adict.keys()) From a3478c70d58c4ddbe50ebd131c57d522ec00123e Mon Sep 17 00:00:00 2001 From: xtreak Date: Sun, 30 Dec 2018 14:17:39 +0530 Subject: [PATCH 2/5] Add tests for prefix match of path --- Lib/test/test_http_cookiejar.py | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/Lib/test/test_http_cookiejar.py b/Lib/test/test_http_cookiejar.py index 8dbea3325d9b99..9b83a3522ba308 100644 --- a/Lib/test/test_http_cookiejar.py +++ b/Lib/test/test_http_cookiejar.py @@ -692,6 +692,28 @@ def test_request_path(self): req = urllib.request.Request("http://www.example.com") self.assertEqual(request_path(req), "/") + def test_path_prefix_match(self): + pol = DefaultCookiePolicy() + + c = CookieJar(pol) + url = "http://bar.com/foo" + interact_netscape(c, url, 'spam=eggs; Path=/foo') + + h = interact_netscape(c, url) + self.assertIn('spam=eggs', h, "path not returned") + + h = interact_netscape(c, "http://bar.com/foo/bar") + self.assertIn('spam=eggs', h, "path not returned") + + h = interact_netscape(c, "http://bar.com/foo/bar/") + self.assertIn('spam=eggs', h, "path not returned") + + h = interact_netscape(c, "http://bar.com/") + self.assertNotIn('spam=eggs', h, "path returned with /") + + h = interact_netscape(c, "http://bar.com/foobad/foo") + self.assertNotIn('spam=eggs', h, "path returned with invalid prefix") + def test_request_port(self): req = urllib.request.Request("http://www.acme.com:1234/", headers={"Host": "www.acme.com:4321"}) From 1e81804a7530c09a295d1b1a66e299ee5613c7e5 Mon Sep 17 00:00:00 2001 From: xtreak Date: Sun, 30 Dec 2018 14:35:35 +0530 Subject: [PATCH 3/5] Add news entry --- .../next/Library/2018-12-30-14-35-19.bpo-35121.oWmiGU.rst | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 Misc/NEWS.d/next/Library/2018-12-30-14-35-19.bpo-35121.oWmiGU.rst diff --git a/Misc/NEWS.d/next/Library/2018-12-30-14-35-19.bpo-35121.oWmiGU.rst b/Misc/NEWS.d/next/Library/2018-12-30-14-35-19.bpo-35121.oWmiGU.rst new file mode 100644 index 00000000000000..032e1e2c00bc5d --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-12-30-14-35-19.bpo-35121.oWmiGU.rst @@ -0,0 +1,3 @@ +Don't set cookie for a request when the request path is a prefix match of +the cookie's path attribute but doesn't end with "/". Patch by Karthikeyan +Singaravelan. From 5dc9237bc25afe038ff2332891efcef27185f8ed Mon Sep 17 00:00:00 2001 From: xtreak Date: Thu, 3 Jan 2019 22:07:38 +0530 Subject: [PATCH 4/5] Fix set_ok_path and refactor tests --- Lib/http/cookiejar.py | 2 +- Lib/test/test_http_cookiejar.py | 36 +++++++++++++++++---------------- 2 files changed, 20 insertions(+), 18 deletions(-) diff --git a/Lib/http/cookiejar.py b/Lib/http/cookiejar.py index 3467dc06210e0f..d0219771fae8da 100644 --- a/Lib/http/cookiejar.py +++ b/Lib/http/cookiejar.py @@ -992,7 +992,7 @@ def set_ok_path(self, cookie, request): req_path = request_path(request) if ((cookie.version > 0 or (cookie.version == 0 and self.strict_ns_set_path)) and - not req_path.startswith(cookie.path)): + not self.path_return_ok(cookie.path, request)): _debug(" path attribute %s is not a prefix of request " "path %s", cookie.path, req_path) return False diff --git a/Lib/test/test_http_cookiejar.py b/Lib/test/test_http_cookiejar.py index 9b83a3522ba308..8bdaf5c5754829 100644 --- a/Lib/test/test_http_cookiejar.py +++ b/Lib/test/test_http_cookiejar.py @@ -694,25 +694,27 @@ def test_request_path(self): def test_path_prefix_match(self): pol = DefaultCookiePolicy() + strict_ns_path_pol = DefaultCookiePolicy(strict_ns_set_path=True) c = CookieJar(pol) - url = "http://bar.com/foo" - interact_netscape(c, url, 'spam=eggs; Path=/foo') - - h = interact_netscape(c, url) - self.assertIn('spam=eggs', h, "path not returned") - - h = interact_netscape(c, "http://bar.com/foo/bar") - self.assertIn('spam=eggs', h, "path not returned") - - h = interact_netscape(c, "http://bar.com/foo/bar/") - self.assertIn('spam=eggs', h, "path not returned") - - h = interact_netscape(c, "http://bar.com/") - self.assertNotIn('spam=eggs', h, "path returned with /") - - h = interact_netscape(c, "http://bar.com/foobad/foo") - self.assertNotIn('spam=eggs', h, "path returned with invalid prefix") + base_url = "http://bar.com" + interact_netscape(c, base_url, 'spam=eggs; Path=/foo') + cookie = c._cookies['bar.com']['/foo']['spam'] + + for path, ok in [('/foo', True), + ('/foo/', True), + ('/foo/bar', True), + ('/', False), + ('/foobad/foo', False)]: + url = f'{base_url}{path}' + req = urllib.request.Request(url) + h = interact_netscape(c, url) + if ok: + self.assertIn('spam=eggs', h, f"cookie not set for {path}") + self.assertTrue(strict_ns_path_pol.set_ok_path(cookie, req)) + else: + self.assertNotIn('spam=eggs', h, f"cookie set for {path}") + self.assertFalse(strict_ns_path_pol.set_ok_path(cookie, req)) def test_request_port(self): req = urllib.request.Request("http://www.acme.com:1234/", From de2c5a4dd9013ed095ccda068c2a5f0b4f1eda51 Mon Sep 17 00:00:00 2001 From: xtreak Date: Thu, 17 Jan 2019 00:52:24 +0530 Subject: [PATCH 5/5] Use slice for last letter --- Lib/http/cookiejar.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Lib/http/cookiejar.py b/Lib/http/cookiejar.py index d0219771fae8da..07ec9785ec3c47 100644 --- a/Lib/http/cookiejar.py +++ b/Lib/http/cookiejar.py @@ -1190,10 +1190,11 @@ def domain_return_ok(self, domain, request): def path_return_ok(self, path, request): _debug("- checking cookie path=%s", path) req_path = request_path(request) + pathlen = len(path) if req_path == path: return True elif (req_path.startswith(path) and - (path.endswith("/") or req_path[len(path)] == "/")): + (path.endswith("/") or req_path[pathlen:pathlen+1] == "/")): return True _debug(" %s does not path-match %s", req_path, path)