From: Yasuhiro Matsumoto Date: Thu, 16 Apr 2026 20:03:39 +0000 (+0000) Subject: patch 9.2.0358: runtime(vimball): still path traversal attacks possible X-Git-Tag: v9.2.0358^0 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=b076c49282f4415ac90b692332887a57a3e8f178;p=thirdparty%2Fvim.git patch 9.2.0358: runtime(vimball): still path traversal attacks possible Problem: runtime(vimball): still path traversal attacks possible Solution: block Windows driver letter paths (Yasuhiro Matsumoto) The path traversal check in vimball#Vimball() did not reject file names starting with a Windows drive letter (e.g. "C:/foo"). Backslashes are normalized to forward slashes earlier, so UNC paths are caught by the leading-slash check, but absolute drive-letter paths slipped through and could write outside of g:vimball_home on Windows. Add a "^\a:" check next to the existing "^/" check, and cover it with a new test. closes: #19989 Signed-off-by: Yasuhiro Matsumoto Signed-off-by: Christian Brabandt --- diff --git a/runtime/autoload/vimball.vim b/runtime/autoload/vimball.vim index d661ded631..8cc206f1d4 100644 --- a/runtime/autoload/vimball.vim +++ b/runtime/autoload/vimball.vim @@ -1,13 +1,10 @@ " vimball.vim : construct a file containing both paths and files " Maintainer: This runtime file is looking for a new maintainer. " Original Author: Charles E. Campbell -" Date: Apr 11, 2016 +" Date: Apr 16, 2026 " Version: 37 (with modifications from the Vim Project) " GetLatestVimScripts: 1502 1 :AutoInstall: vimball.vim " Last Change: -" 2025 Feb 28 by Vim Project: add support for bzip3 (#16755) -" 2026 Apr 05 by Vim Project: Detect path traversal attacks -" 2026 Apr 09 by Vim Project: Detect more path traversal attacks " Copyright: (c) 2004-2011 by Charles E. Campbell " The VIM LICENSE applies to Vimball.vim, and Vimball.txt " (see |copyright|) except use "Vimball" instead of "Vim". @@ -230,8 +227,11 @@ fun! vimball#Vimball(really,...) let fsize = substitute(getline(linenr+1),'^\(\d\+\).\{-}$','\1','')+0 let fenc = substitute(getline(linenr+1),'^\d\+\s*\(\S\{-}\)$','\1','') let filecnt = filecnt + 1 - " Do not allow a leading / or .. anywhere in the file name - if fname =~ '\.\.' || fname =~ '^/' + " Do not allow a leading /, .. anywhere, or a Windows drive letter + " (e.g. C:/foo) in the file name. Backslashes were already converted + " to forward slashes above, so this also catches \\server\share UNC + " paths via the leading-slash check. + if fname =~ '\.\.' || fname =~ '^/' || fname =~ '^\a:' echomsg "(Vimball) Path Traversal Attack detected, aborting..." exe "tabn ".curtabnr bw! Vimball diff --git a/runtime/doc/pi_vimball.txt b/runtime/doc/pi_vimball.txt index 07fc68f7eb..e1770e289e 100644 --- a/runtime/doc/pi_vimball.txt +++ b/runtime/doc/pi_vimball.txt @@ -1,4 +1,4 @@ -*pi_vimball.txt* For Vim version 9.2. Last change: 2026 Apr 05 +*pi_vimball.txt* For Vim version 9.2. Last change: 2026 Apr 16 ---------------- Vimball Archiver @@ -166,6 +166,11 @@ WINDOWS *vimball-windows* ============================================================================== 4. Vimball History *vimball-history* {{{1 + unreleased: + Feb 28, 2025 * add support for bzip3 (#16755) + Apr 05, 2026 * Detect path traversal attacks + Apr 09, 2026 * Detect more path traversal attacks + Apr 16, 2026 * Block Windows drive letter paths 37 : Jul 18, 2014 * (by request of T. Miedema) added augroup around the autocmds in vimballPlugin.vim Jul 06, 2015 * there are two uses of tabc; changed to tabc! diff --git a/src/testdir/test_plugin_vimball.vim b/src/testdir/test_plugin_vimball.vim index 2d5b4ba768..ab740d1d2b 100644 --- a/src/testdir/test_plugin_vimball.vim +++ b/src/testdir/test_plugin_vimball.vim @@ -83,3 +83,17 @@ func Test_vimball_path_traversal() call assert_false(filereadable('../XVimball/Xtest.txt')) call s:teardown() endfunc + +func Test_vimball_path_traversal_drive_letter() + call s:Mkvimball() + call delete('XVimball', 'rf') + sp Xtest.vmb + " try to write to a Windows-style absolute path with a drive letter + 4s#XVimball#C:/&# + so % + call feedkeys("\", "it") + + let mess = execute(':mess')->split('\n')[-1] + call assert_match('(Vimball) Path Traversal Attack detected, aborting\.\.\.', mess) + call s:teardown() +endfunc diff --git a/src/version.c b/src/version.c index 6716d470b3..a836743b7a 100644 --- a/src/version.c +++ b/src/version.c @@ -734,6 +734,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 358, /**/ 357, /**/