patch 9.2.0299: runtime(zip): may write using absolute paths

Problem:  runtime(zip): may write using absolute paths
          (syndicate)
Solution: Detect this case and abort on Unix, warn in the documentation
          about possible issues

Signed-off-by: Christian Brabandt <cb@256bit.org>
This commit is contained in:
Christian Brabandt
2026-04-05 15:58:00 +00:00
parent 5943c57173
commit 46f530e517
5 changed files with 34 additions and 1 deletions
+8
View File
@@ -21,6 +21,7 @@
" 2026 Feb 08 by Vim Project: use system() instead of :!
" 2026 Mar 08 by Vim Project: Make ZipUpdatePS() check for powershell
" 2026 Apr 01 by Vim Project: Detect more path traversal attacks
" 2026 Apr 05 by Vim Project: Detect more path traversal attacks
" License: Vim License (see vim's :help license)
" Copyright: Copyright (C) 2005-2019 Charles E. Campbell {{{1
" Permission is hereby granted to use and distribute this code,
@@ -395,9 +396,16 @@ fun! zip#Write(fname)
if has("unix")
let zipfile = substitute(a:fname,'zipfile://\(.\{-}\)::[^\\].*$','\1','')
let fname = substitute(a:fname,'zipfile://.\{-}::\([^\\].*\)$','\1','')
" fname should not start with a leading slash to avoid writing anywhere into the system
if fname =~ '^/'
call s:Mess('Error', "***error*** (zip#Write) Path Traversal Attack detected, not writing!")
call s:ChgDir(curdir,s:WARNING,"(zip#Write) unable to return to ".curdir."!")
return
endif
else
let zipfile = substitute(a:fname,'^.\{-}zipfile://\(.\{-}\)::[^\\].*$','\1','')
let fname = substitute(a:fname,'^.\{-}zipfile://.\{-}::\([^\\].*\)$','\1','')
" TODO: what to check on MS-Windows to avoid writing absolute paths?
endif
if fname =~ '^[.]\{1,2}/'
let gnu_cmd = g:zip_zipcmd . ' -d ' . s:Escape(fnamemodify(zipfile,":p"),0) . ' ' . s:Escape(fname,0)
+5 -1
View File
@@ -1,4 +1,4 @@
*pi_zip.txt* For Vim version 9.2. Last change: 2026 Feb 14
*pi_zip.txt* For Vim version 9.2. Last change: 2026 Apr 05
+====================+
| Zip File Interface |
@@ -33,6 +33,10 @@ Copyright: Copyright (C) 2005-2015 Charles E Campbell *zip-copyright*
also write to the file. Currently, one may not make a new file in
zip archives via the plugin.
The zip plugin tries to detect some common path traversal attack
patterns, but it may not catch all possible cases. Please be very
careful when using this plugin with untrusted input.
COMMANDS~
*zip-x*
x : extract a listed file when the cursor is atop it
Binary file not shown.
+19
View File
@@ -296,3 +296,22 @@ def g:Test_zip_fname_evil_path2()
assert_match('zipfile://.*::.*tmp/foobar', @%)
bw!
enddef
def g:Test_zip_fname_evil_path3()
CheckNotMSWindows
# needed for writing the zip file
CheckExecutable zip
CopyZipFile("evil.zip")
defer delete("X.zip")
e X.zip
:1
var fname = 'payload.txt'
search('\V' .. fname)
exe "normal \<cr>"
:w!
var mess = execute(':mess')
assert_match('Path Traversal Attack', mess)
bw!
enddef
+2
View File
@@ -734,6 +734,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
299,
/**/
298,
/**/