From c3c06723f01de2ff2cb3edfe1896adb05b5921ee Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Thu, 16 Apr 2026 08:40:41 +0800 Subject: [PATCH] vim-patch:9.2.0355: runtime(tar): missing path traversal checks in tar#Extract() (#39095) Problem: runtime(tar): missing path traversal checks in tar#Extract() Solution: Add check for leading slash, however gnu tar should already detect this (q1uf3ng) tar#Extract() did not check for ../ sequences or absolute paths, unlike zip#Extract() which was patched in recent commits. Add the same checks: ../ (relative traversal), leading slash (Unix), drive letter and UNC/leading slash (Windows). closes: vim/vim#19981 https://github.com/vim/vim/commit/490b737f3e172c3c66744c7531ee85f19618419d Co-authored-by: q1uf3ng --- runtime/autoload/tar.vim | 19 +++++++++++++++++++ test/old/testdir/test_plugin_tar.vim | 5 +++++ 2 files changed, 24 insertions(+) diff --git a/runtime/autoload/tar.vim b/runtime/autoload/tar.vim index 0ae657c0d6..223ede31c4 100644 --- a/runtime/autoload/tar.vim +++ b/runtime/autoload/tar.vim @@ -22,6 +22,7 @@ " 2026 Apr 06 by Vim Project: fix bugs with lz4 support (#19925) " 2026 Apr 09 by Vim Project: fix bugs with zstd support (#19930) " 2026 Apr 09 by Vim Project: fix bug with dotted filename (#19930) +" 2026 Apr 15 by Vim Project: fix more path traversal issues (#19981) " " Contains many ideas from Michael Toren's " @@ -611,6 +612,24 @@ fun! tar#Extract() let &report= repkeep return endif + if fname =~ '^[.]\?[.]/' || simplify(fname) =~ '\.\.[/\\]' + call s:Msg('tar#Extract', 'error', "Path Traversal Attack detected, not extracting!") + let &report= repkeep + return + endif + if has("unix") + if fname =~ '^/' + call s:Msg('tar#Extract', 'error', "Path Traversal Attack detected, not extracting!") + let &report= repkeep + return + endif + else + if fname =~ '^\%(\a:[\\/]\|[\\/]\)' + call s:Msg('tar#Extract', 'error', "Path Traversal Attack detected, not extracting!") + let &report= repkeep + return + endif + endif let extractcmd= s:WinPath(g:tar_extractcmd) let tarball = expand("%") diff --git a/test/old/testdir/test_plugin_tar.vim b/test/old/testdir/test_plugin_tar.vim index f6746fdd47..2152fe701e 100644 --- a/test/old/testdir/test_plugin_tar.vim +++ b/test/old/testdir/test_plugin_tar.vim @@ -88,6 +88,11 @@ func Test_tar_evil() call assert_equal("X.tar", @%) call assert_equal(1, b:leading_slash) + "## Press x to extract + :6 + let mess = execute(":normal x", '') + call assert_match('(tar#Extract) Path Traversal Attack detected, not extracting!', mess) + "## Check ENTER on file :6 exe ":normal \"