91 lines
3.4 KiB
Diff
91 lines
3.4 KiB
Diff
From 3d5dd1eee265ec43dd96d89656c2a1c207dd5815 Mon Sep 17 00:00:00 2001
|
|
From: "Miss Islington (bot)"
|
|
<31488909+miss-islington@users.noreply.github.com>
|
|
Date: Mon, 22 May 2023 03:41:30 -0700
|
|
Subject: [PATCH] [3.9] gh-99889: Fix directory traversal security flaw in
|
|
uu.decode() (GH-104096) (#104331)
|
|
|
|
(cherry picked from commit 0aeda297931820436a50b78f4f7f0597274b5df4)
|
|
|
|
Co-authored-by: Sam Carroll <70000253+samcarroll42@users.noreply.github.com>
|
|
---
|
|
Lib/test/test_uu.py | 28 +++++++++++++++++++
|
|
Lib/uu.py | 9 +++++-
|
|
...3-05-02-17-56-32.gh-issue-99889.l664SU.rst | 2 ++
|
|
3 files changed, 38 insertions(+), 1 deletion(-)
|
|
mode change 100755 => 100644 Lib/uu.py
|
|
create mode 100644 Misc/NEWS.d/next/Security/2023-05-02-17-56-32.gh-issue-99889.l664SU.rst
|
|
|
|
diff --git a/Lib/test/test_uu.py b/Lib/test/test_uu.py
|
|
index 4c639b7bd5..410eb8e392 100644
|
|
--- a/Lib/test/test_uu.py
|
|
+++ b/Lib/test/test_uu.py
|
|
@@ -145,6 +145,34 @@ def test_newlines_escaped(self):
|
|
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):
|
|
diff --git a/Lib/uu.py b/Lib/uu.py
|
|
old mode 100755
|
|
new mode 100644
|
|
index 9f1f37f1a6..9fe252a639
|
|
--- a/Lib/uu.py
|
|
+++ b/Lib/uu.py
|
|
@@ -130,7 +130,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)
|
|
#
|
|
diff --git a/Misc/NEWS.d/next/Security/2023-05-02-17-56-32.gh-issue-99889.l664SU.rst b/Misc/NEWS.d/next/Security/2023-05-02-17-56-32.gh-issue-99889.l664SU.rst
|
|
new file mode 100644
|
|
index 0000000000..b7002e81b6
|
|
--- /dev/null
|
|
+++ b/Misc/NEWS.d/next/Security/2023-05-02-17-56-32.gh-issue-99889.l664SU.rst
|
|
@@ -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.
|
|
--
|
|
2.33.0
|
|
|