aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichał Górny <mgorny@gentoo.org>2022-03-18 12:26:44 +0100
committerMichał Górny <mgorny@gentoo.org>2022-03-18 12:26:44 +0100
commite972fd923fd5172aa04c8f9d8775f1590ebbe394 (patch)
tree0dba57730614d307e76b3b06f44eda8be8b50a65
parentbpo-46811: Make test suite support Expat >=2.4.5 (GH-31453) (diff)
downloadcpython-e972fd923fd5172aa04c8f9d8775f1590ebbe394.tar.gz
cpython-e972fd923fd5172aa04c8f9d8775f1590ebbe394.tar.bz2
cpython-e972fd923fd5172aa04c8f9d8775f1590ebbe394.zip
bpo-46756: Fix authorization check in urllib.request (GH-31353)
Fix a bug in urllib.request.HTTPPasswordMgr.find_user_password() and urllib.request.HTTPPasswordMgrWithPriorAuth.is_authenticated() which allowed to bypass authorization. For example, access to URI "example.org/foobar" was allowed if the user was authorized for URI "example.org/foo". (rebased for 2.7 by Michał Górny)
-rw-r--r--Lib/test/test_urllib2.py17
-rw-r--r--Lib/urllib2.py8
2 files changed, 21 insertions, 4 deletions
diff --git a/Lib/test/test_urllib2.py b/Lib/test/test_urllib2.py
index 0adbb13c43a..6acab896785 100644
--- a/Lib/test/test_urllib2.py
+++ b/Lib/test/test_urllib2.py
@@ -137,6 +137,7 @@ def test_password_manager(self):
>>> add("Some Realm", "http://example.com/ni", "ni", "ni")
>>> add("c", "http://example.com/foo", "foo", "ni")
>>> add("c", "http://example.com/bar", "bar", "nini")
+ >>> add("c", "http://example.com/foo/bar", "foobar", "nibar")
>>> add("b", "http://example.com/", "first", "blah")
>>> add("b", "http://example.com/", "second", "spam")
>>> add("a", "http://example.com", "1", "a")
@@ -158,6 +159,22 @@ def test_password_manager(self):
('foo', 'ni')
>>> mgr.find_user_password("c", "http://example.com/bar")
('bar', 'nini')
+ >>> mgr.find_user_password("c", "http://example.com/foo/")
+ ('foo', 'ni')
+ >>> mgr.find_user_password("c", "http://example.com/foo/bar")
+ ('foo', 'ni')
+ >>> mgr.find_user_password("c", "http://example.com/foo/baz")
+ ('foo', 'ni')
+ >>> mgr.find_user_password("c", "http://example.com/foobar")
+ (None, None)
+
+ >>> add("c", "http://example.com/baz/", "baz", "ninini")
+ >>> mgr.find_user_password("c", "http://example.com/baz")
+ (None, None)
+ >>> mgr.find_user_password("c", "http://example.com/baz/")
+ ('baz', 'ninini')
+ >>> mgr.find_user_password("c", "http://example.com/baz/bar")
+ ('baz', 'ninini')
Actually, this is really undefined ATM
## Currently, we use the highest-level path where more than one match:
diff --git a/Lib/urllib2.py b/Lib/urllib2.py
index c92fb6afb89..f45ef57ee32 100644
--- a/Lib/urllib2.py
+++ b/Lib/urllib2.py
@@ -833,10 +833,10 @@ class HTTPPasswordMgr:
return True
if base[0] != test[0]:
return False
- common = posixpath.commonprefix((base[1], test[1]))
- if len(common) == len(base[1]):
- return True
- return False
+ prefix = base[1]
+ if prefix[-1:] != '/':
+ prefix += '/'
+ return test[1].startswith(prefix)
class HTTPPasswordMgrWithDefaultRealm(HTTPPasswordMgr):