diff options
author | Michał Górny <mgorny@gentoo.org> | 2022-03-18 12:26:44 +0100 |
---|---|---|
committer | Michał Górny <mgorny@gentoo.org> | 2022-03-18 12:26:44 +0100 |
commit | e972fd923fd5172aa04c8f9d8775f1590ebbe394 (patch) | |
tree | 0dba57730614d307e76b3b06f44eda8be8b50a65 | |
parent | bpo-46811: Make test suite support Expat >=2.4.5 (GH-31453) (diff) | |
download | cpython-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.py | 17 | ||||
-rw-r--r-- | Lib/urllib2.py | 8 |
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): |