From: Miss Islington (bot) <31488909+miss-islington@users.noreply.github.com> Date: Sat, 6 Jun 2026 10:29:57 +0000 (+0200) Subject: [3.15] gh-149835: Use realpath() instead of abspath() in shutil.move() (GH-149986... X-Git-Url: http://git.ipfire.org/gitweb/index.cgi?a=commitdiff_plain;h=0a2e7af44bba26265ba9932fd9637bf1954d1806;p=thirdparty%2FPython%2Fcpython.git [3.15] gh-149835: Use realpath() instead of abspath() in shutil.move() (GH-149986) (GH-151009) (cherry picked from commit fab449bddbc4ff03677d49448cf6ea1f9d6a319f) Co-authored-by: Thomas Kowalski --- diff --git a/Lib/shutil.py b/Lib/shutil.py index 45cbe4c855b4..d3ac5dc5c50a 100644 --- a/Lib/shutil.py +++ b/Lib/shutil.py @@ -940,8 +940,8 @@ def move(src, dst, copy_function=copy2): return real_dst def _destinsrc(src, dst): - src = os.path.abspath(src) - dst = os.path.abspath(dst) + src = os.path.realpath(src) + dst = os.path.realpath(dst) if not src.endswith(os.path.sep): src += os.path.sep if not dst.endswith(os.path.sep): diff --git a/Lib/test/test_shutil.py b/Lib/test/test_shutil.py index 13a3487382df..c2485e20a199 100644 --- a/Lib/test/test_shutil.py +++ b/Lib/test/test_shutil.py @@ -2914,6 +2914,23 @@ class TestMove(BaseTest, unittest.TestCase): finally: os_helper.rmtree(TESTFN) + @os_helper.skip_unless_symlink + def test_destinsrc_symlink_bypass(self): + tmp = self.mkdtemp() + src = os.path.join(tmp, 'src') + os.makedirs(src) + # tmp/link -> tmp (one level up) + link = os.path.join(tmp, 'link') + os.symlink(tmp, link) + # raw path: tmp/link/src/sub - no src prefix in string space + # real path: tmp/src/sub - physically inside src + dst = os.path.join(link, 'src', 'sub') + self.assertTrue( + shutil._destinsrc(src, dst), + msg='_destinsrc failed to detect dst inside src via symlink ' + '(dst=%s, src=%s)' % (dst, src), + ) + @os_helper.skip_unless_symlink @mock_rename def test_move_file_symlink(self): diff --git a/Misc/NEWS.d/next/Security/2026-05-18-17-46-00.gh-issue-149835.EebFlk.rst b/Misc/NEWS.d/next/Security/2026-05-18-17-46-00.gh-issue-149835.EebFlk.rst new file mode 100644 index 000000000000..20cab7365524 --- /dev/null +++ b/Misc/NEWS.d/next/Security/2026-05-18-17-46-00.gh-issue-149835.EebFlk.rst @@ -0,0 +1,3 @@ +:func:`shutil.move` now resolves symlinks via :func:`os.path.realpath` +when checking whether the destination is inside the source directory, +preventing a symlink-based bypass of that guard.