mirror of
https://github.com/neovim/neovim.git
synced 2026-04-20 14:25:32 +00:00
vim-patch:9.2.0299: runtime(zip): may write using absolute paths (#38810)
Problem: runtime(zip): may write using absolute paths
(syndicate)
Solution: Detect this case and abort on Unix, warn in the documentation
about possible issues
46f530e517
Co-authored-by: Christian Brabandt <cb@256bit.org>
(cherry picked from commit 4aa8969d29)
This commit is contained in:
committed by
github-actions[bot]
parent
f92a68d4bc
commit
bf084967d7
@@ -21,6 +21,7 @@
|
|||||||
" 2026 Feb 08 by Vim Project: use system() instead of :!
|
" 2026 Feb 08 by Vim Project: use system() instead of :!
|
||||||
" 2026 Mar 08 by Vim Project: Make ZipUpdatePS() check for powershell
|
" 2026 Mar 08 by Vim Project: Make ZipUpdatePS() check for powershell
|
||||||
" 2026 Apr 01 by Vim Project: Detect more path traversal attacks
|
" 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)
|
" License: Vim License (see vim's :help license)
|
||||||
" Copyright: Copyright (C) 2005-2019 Charles E. Campbell {{{1
|
" Copyright: Copyright (C) 2005-2019 Charles E. Campbell {{{1
|
||||||
" Permission is hereby granted to use and distribute this code,
|
" Permission is hereby granted to use and distribute this code,
|
||||||
@@ -395,9 +396,16 @@ fun! zip#Write(fname)
|
|||||||
if has("unix")
|
if has("unix")
|
||||||
let zipfile = substitute(a:fname,'zipfile://\(.\{-}\)::[^\\].*$','\1','')
|
let zipfile = substitute(a:fname,'zipfile://\(.\{-}\)::[^\\].*$','\1','')
|
||||||
let fname = 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
|
else
|
||||||
let zipfile = substitute(a:fname,'^.\{-}zipfile://\(.\{-}\)::[^\\].*$','\1','')
|
let zipfile = substitute(a:fname,'^.\{-}zipfile://\(.\{-}\)::[^\\].*$','\1','')
|
||||||
let fname = 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
|
endif
|
||||||
if fname =~ '^[.]\{1,2}/'
|
if fname =~ '^[.]\{1,2}/'
|
||||||
let gnu_cmd = g:zip_zipcmd . ' -d ' . s:Escape(fnamemodify(zipfile,":p"),0) . ' ' . s:Escape(fname,0)
|
let gnu_cmd = g:zip_zipcmd . ' -d ' . s:Escape(fnamemodify(zipfile,":p"),0) . ' ' . s:Escape(fname,0)
|
||||||
|
|||||||
@@ -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
|
also write to the file. Currently, one may not make a new file in
|
||||||
zip archives via the plugin.
|
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~
|
COMMANDS~
|
||||||
*zip-x*
|
*zip-x*
|
||||||
x : extract a listed file when the cursor is atop it
|
x : extract a listed file when the cursor is atop it
|
||||||
|
|||||||
Binary file not shown.
@@ -297,3 +297,22 @@ func Test_zip_fname_evil_path2()
|
|||||||
call assert_match('zipfile://.*::.*tmp/foobar', @%)
|
call assert_match('zipfile://.*::.*tmp/foobar', @%)
|
||||||
bw!
|
bw!
|
||||||
endfunc
|
endfunc
|
||||||
|
|
||||||
|
func Test_zip_fname_evil_path3()
|
||||||
|
CheckNotMSWindows
|
||||||
|
" needed for writing the zip file
|
||||||
|
CheckExecutable zip
|
||||||
|
|
||||||
|
call s:CopyZipFile("evil.zip")
|
||||||
|
defer delete("X.zip")
|
||||||
|
e X.zip
|
||||||
|
|
||||||
|
:1
|
||||||
|
let fname = 'payload.txt'
|
||||||
|
call search('\V' .. fname)
|
||||||
|
exe "normal \<cr>"
|
||||||
|
:w!
|
||||||
|
let mess = execute(':mess')
|
||||||
|
call assert_match('Path Traversal Attack', mess)
|
||||||
|
bw!
|
||||||
|
endfunc
|
||||||
|
|||||||
Reference in New Issue
Block a user