Commit: runtime(zip): also block single leading slash and absolute paths in Extract

4 views
Skip to first unread message

Christian Brabandt

unread,
Apr 15, 2026, 12:15:14 PMApr 15
to vim...@googlegroups.com
runtime(zip): also block single leading slash and absolute paths in Extract

Commit: https://github.com/vim/vim/commit/351a16c88f56aeeca5e06095624dd701b264b2a9
Author: q1uf3ng <q1u...@protone.me>
Date: Wed Apr 15 04:03:02 2026 +0000

runtime(zip): also block single leading slash and absolute paths in Extract

zip#Write(): the Windows path check did not match a single leading
slash (/path), which resolves to the current drive root on Windows.
Simplify the regex to match any leading slash or backslash.

zip#Extract(): add absolute path checks for both Unix and Windows,
matching the existing checks in zip#Write().

closes: #19976

Signed-off-by: q1uf3ng <gl...@protonmail.com>
Signed-off-by: Christian Brabandt <c...@256bit.org>

diff --git a/runtime/autoload/zip.vim b/runtime/autoload/zip.vim
index 6a2d6daa3..aad548239 100644
--- a/runtime/autoload/zip.vim
+++ b/runtime/autoload/zip.vim
@@ -23,6 +23,7 @@
" 2026 Apr 01 by Vim Project: Detect more path traversal attacks
" 2026 Apr 05 by Vim Project: Detect more path traversal attacks
" 2026 Apr 14 by Vim Project: Detect more path traversal attacks on Windows
+" 2026 Apr 15 by Vim Project: Detect more path traversal attacks on Windows
" 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,
@@ -406,8 +407,8 @@ fun! zip#Write(fname)
else
let zipfile = substitute(a:fname,'^.\{-}zipfile://\(.\{-}\)::[^\].*$',' ','')
let fname = substitute(a:fname,'^.\{-}zipfile://.\{-}::\([^\].*\)$',' ','')
- " fname should not start with drive leter or a UNC path
- if fname =~ '^\%(\%( :[\/]\)\|[\/]\{2}\)'
+ " fname should not start with drive letter, UNC path, or leading slash
+ 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
@@ -505,6 +506,18 @@ fun! zip#Extract()
call s:Mess('Error', "***error*** (zip#Browse) Path Traversal Attack detected, not extracting!")
return
endif
+ " block absolute paths
+ if has("unix")
+ if fname =~ '^/'
+ call s:Mess('Error', "***error*** (zip#Extract) Path Traversal Attack detected, not extracting!")
+ return
+ endif
+ else
+ if fname =~ '^\%( :[\/]\|[\/]\)'
+ call s:Mess('Error', "***error*** (zip#Extract) Path Traversal Attack detected, not extracting!")
+ return
+ endif
+ endif
if filereadable(fname)
call s:Mess('Error', "***error*** (zip#Extract) <" .. fname .."> already exists in directory, not overwriting!")
return
Reply all
Reply to author
Forward
0 new messages