mirror of
https://github.com/python/cpython.git
synced 2025-09-26 18:29:57 +00:00
gh-99889: Fix directory traversal security flaw in uu.decode() (#104096)
* Fix directory traversal security flaw in uu.decode() * also check absolute paths and os.altsep * Add a regression test. --------- Co-authored-by: Gregory P. Smith <greg@krypto.org> [Google]
This commit is contained in:
parent
afe7703744
commit
0aeda29793
3 changed files with 38 additions and 1 deletions
|
@ -147,6 +147,34 @@ class UUTest(unittest.TestCase):
|
|||
uu.encode(inp, out, filename)
|
||||
self.assertIn(safefilename, out.getvalue())
|
||||
|
||||
def test_no_directory_traversal(self):
|
||||
relative_bad = b"""\
|
||||
begin 644 ../../../../../../../../tmp/test1
|
||||
$86)C"@``
|
||||
`
|
||||
end
|
||||
"""
|
||||
with self.assertRaisesRegex(uu.Error, 'directory'):
|
||||
uu.decode(io.BytesIO(relative_bad))
|
||||
if os.altsep:
|
||||
relative_bad_bs = relative_bad.replace(b'/', b'\\')
|
||||
with self.assertRaisesRegex(uu.Error, 'directory'):
|
||||
uu.decode(io.BytesIO(relative_bad_bs))
|
||||
|
||||
absolute_bad = b"""\
|
||||
begin 644 /tmp/test2
|
||||
$86)C"@``
|
||||
`
|
||||
end
|
||||
"""
|
||||
with self.assertRaisesRegex(uu.Error, 'directory'):
|
||||
uu.decode(io.BytesIO(absolute_bad))
|
||||
if os.altsep:
|
||||
absolute_bad_bs = absolute_bad.replace(b'/', b'\\')
|
||||
with self.assertRaisesRegex(uu.Error, 'directory'):
|
||||
uu.decode(io.BytesIO(absolute_bad_bs))
|
||||
|
||||
|
||||
class UUStdIOTest(unittest.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
|
|
9
Lib/uu.py
Executable file → Normal file
9
Lib/uu.py
Executable file → Normal file
|
@ -133,7 +133,14 @@ def decode(in_file, out_file=None, mode=None, quiet=False):
|
|||
# If the filename isn't ASCII, what's up with that?!?
|
||||
out_file = hdrfields[2].rstrip(b' \t\r\n\f').decode("ascii")
|
||||
if os.path.exists(out_file):
|
||||
raise Error('Cannot overwrite existing file: %s' % out_file)
|
||||
raise Error(f'Cannot overwrite existing file: {out_file}')
|
||||
if (out_file.startswith(os.sep) or
|
||||
f'..{os.sep}' in out_file or (
|
||||
os.altsep and
|
||||
(out_file.startswith(os.altsep) or
|
||||
f'..{os.altsep}' in out_file))
|
||||
):
|
||||
raise Error(f'Refusing to write to {out_file} due to directory traversal')
|
||||
if mode is None:
|
||||
mode = int(hdrfields[1], 8)
|
||||
#
|
||||
|
|
|
@ -0,0 +1,2 @@
|
|||
Fixed a security in flaw in :func:`uu.decode` that could allow for
|
||||
directory traversal based on the input if no ``out_file`` was specified.
|
Loading…
Add table
Add a link
Reference in a new issue