Join GitHub today
GitHub is home to over 40 million developers working together to host and review code, manage projects, and build software together.
Sign up[2.7] bpo-35907: Avoid file reading as disallowing the unnecessary URL scheme in urllib (GH-11842) #11842
Conversation
…me in urllib
This comment has been minimized.
This comment has been minimized.
the-knights-who-say-ni
commented
Feb 13, 2019
Hello, and thanks for your contribution! I'm a bot set up to make sure that the project can legally accept your contribution by verifying you have signed the PSF contributor agreement (CLA). Our records indicate we have not received your CLA. For legal reasons we need you to sign this before we can look at your contribution. Please follow the steps outlined in the CPython devguide to rectify this issue. If you have recently signed the CLA, please wait at least one business day You can check yourself to see if the CLA has been received. Thanks again for your contribution, we look forward to reviewing it! |
This comment has been minimized.
This comment has been minimized.
tomashek
commented
Apr 8, 2019
Is this patch the accepted resolution for CVE-2019-9948? If so, when is it expected to be merged? |
Misc/NEWS.d/next/Library/2019-02-13-17-21-10.bpo-35907.ckk2zg.rst
Outdated
Show resolved
Hide resolved
|
||
# bpo-35907: # disallow the file reading with the type not allowed | ||
if not hasattr(self, name) or \ | ||
(self == _urlopener and name == 'open_local_file'): |
This comment has been minimized.
This comment has been minimized.
tiran
May 13, 2019
Member
Please simplify the fix. There is no need to check for _urlopener
here. Just block all access to local_file://
schema. We don't need special cases for subclasses or special instances.
This comment has been minimized.
This comment has been minimized.
push0ebp
May 19, 2019
Author
Contributor
If it does not check the instance type of self, all of overridden open_local_file
method will be blocked.
will be okay?
like this
self.assertRaises(IOError, DummyURLopener().open
'local_file://example')
self.assertRaises(IOError, DummyURLopener().open
'local-file://example')
I think that it needs to check open_local_file is overridden.
What do you think?
This comment has been minimized.
This comment has been minimized.
push0ebp
May 19, 2019
Author
Contributor
I think it has to expect this test result.
def test_local_file_open(self):
class DummyURLopener(urllib.URLopener):
def open_local_file(self, url):
return url
class DummyURLopener2(urllib.URLopener):
def open_test(self, url):
return url
opener = DummyURLopener()
opener2 = DummyURLopener2()
for url in ('local-file://example', 'local_file://example'):
self.assertEqual(opener.open(url), '//example')
self.assertRaises(IOError, urllib.urlopen, url)
self.assertRaises(IOError, opener2.open, url)
self.assertEqual(opener2.open('test://example'), '//example')
but Considering the overriding method and instance type check was complex.
If you have a better idea. let me know.
This comment has been minimized.
This comment has been minimized.
bedevere-bot
commented
May 13, 2019
A Python core developer has requested some changes be made to your pull request before we can consider merging it. If you could please address their requests along with any other requests in other reviews from core developers that would be appreciated. Once you have made the requested changes, please leave a comment on this pull request containing the phrase |
I have made the requested changes; please review again. |
Misc/NEWS.d/next/Library/2019-02-13-17-21-10.bpo-35907.ckk2zg.rst
Outdated
Show resolved
Hide resolved
|
||
# bpo-35907: # disallow the file reading with the type not allowed | ||
if not hasattr(self, name) or \ | ||
(self == _urlopener and name == 'open_local_file'): |
This comment has been minimized.
This comment has been minimized.
push0ebp
May 19, 2019
Author
Contributor
If it does not check the instance type of self, all of overridden open_local_file
method will be blocked.
will be okay?
like this
self.assertRaises(IOError, DummyURLopener().open
'local_file://example')
self.assertRaises(IOError, DummyURLopener().open
'local-file://example')
I think that it needs to check open_local_file is overridden.
What do you think?
|
||
# bpo-35907: # disallow the file reading with the type not allowed | ||
if not hasattr(self, name) or \ | ||
(self == _urlopener and name == 'open_local_file'): |
This comment has been minimized.
This comment has been minimized.
push0ebp
May 19, 2019
Author
Contributor
I think it has to expect this test result.
def test_local_file_open(self):
class DummyURLopener(urllib.URLopener):
def open_local_file(self, url):
return url
class DummyURLopener2(urllib.URLopener):
def open_test(self, url):
return url
opener = DummyURLopener()
opener2 = DummyURLopener2()
for url in ('local-file://example', 'local_file://example'):
self.assertEqual(opener.open(url), '//example')
self.assertRaises(IOError, urllib.urlopen, url)
self.assertRaises(IOError, opener2.open, url)
self.assertEqual(opener2.open('test://example'), '//example')
but Considering the overriding method and instance type check was complex.
If you have a better idea. let me know.
|
||
# bpo-35907: # disallow the file reading with the type not allowed | ||
if not hasattr(self, name) or \ | ||
getattr(self, name) == self.open_local_file: |
This comment has been minimized.
This comment has been minimized.
vstinner
May 20, 2019
Member
Another fix is to rename the open_local_file() as _open_local_file(). But... In Python 2.7, there is a risk that the method is called directly in 3rd party code for whatever reason :-(
This comment has been minimized.
This comment has been minimized.
tiran
May 20, 2019
Member
Why do you compare function objects instead of simply name == "open_local_file"
?
This comment has been minimized.
This comment has been minimized.
push0ebp
May 20, 2019
•
Author
Contributor
@tiran
If someone rename open_local_file()
method and also forgets to modify name == "open_local_file"
, it may be bypassed.
So I made the mitigation compare the object to raise syntax error.
Should I do change back?
This comment has been minimized.
This comment has been minimized.
vstinner
May 20, 2019
Member
I concur with Christian, please test directly the name, remove getattr().
This comment has been minimized.
This comment has been minimized.
push0ebp
May 20, 2019
Author
Contributor
@vstinner
I agree with you. I also considered renaming the open_local_file()
. I think that this fix can guarantees availability to the developers who want to override this method. But I chose another fix to minimize side effects for third party codes.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
push0ebp
May 21, 2019
Author
Contributor
Yes. I will do it. I want suggest you other fix.
if not hasattr(self, name):
if proxy:
return self.open_unknown_proxy(proxy, fullurl, data)
else:
return self.open_unknown(fullurl, data)
if name == 'open_local_file':
raise IOError, ('url error', 'invalid url type', urltype)
try:
I think that it is better to raise exception with explicit error message for developers to overriding open_local_file()
.
they can easily recognize local_file
is invalid type.
What do you think about it?
or should I use open_unknown()
?
if not hasattr(self, name) or \
name == 'open_local_file':
This comment has been minimized.
This comment has been minimized.
vstinner
May 21, 2019
Member
# bpo-35907: disallow the file reading with the type not allowed
if not hasattr(self, name) or name == 'open_local_file': ...
LGTM.
if name == 'open_local_file':
raise IOError, ('url error', 'invalid url type', urltype)
That's wrong exception type, don't do that.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
LGTM. |
Modify the object to string in check method name.
LGTM. Just curious about the # which looks like a typo. |
@@ -203,7 +203,9 @@ def open(self, fullurl, data=None): | |||
name = 'open_' + urltype | |||
self.type = urltype | |||
name = name.replace('-', '_') | |||
if not hasattr(self, name): | |||
|
|||
# bpo-35907: # disallow the file reading with the type not allowed |
This comment has been minimized.
This comment has been minimized.
vstinner
May 21, 2019
Member
I don't understand the # in "# bpo-35907: # disallow ...". Is it a typo?
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
Fix typo
b15bde8
into
python:2.7
This comment has been minimized.
This comment has been minimized.
Thanks @push0ebp for the fix! |
This comment has been minimized.
This comment has been minimized.
Thank you for your accept. |
push0ebp commentedFeb 13, 2019
•
edited
https://bugs.python.org/issue35907