neovim

Neovim text editor
git clone https://git.dasho.dev/neovim.git
Log | Files | Refs | README

commit b25527d20d9a5ae25f4a5e2d2d487e2eac731b2c
parent 90d1260cb84c917653987c0dfdfa150b617f5a0f
Author: zeertzjq <zeertzjq@outlook.com>
Date:   Thu, 13 Mar 2025 08:47:02 +0800

vim-patch:9.1.1198: [security]: potential data loss with zip.vim (#32867)

Problem:  [security]: potential data loss with zip.vim and special
          crafted zip files (RyotaK)
Solution: use glob '[-]' to protect filenames starting with '-'

Github Advisory:
https://github.com/vim/vim/security/advisories/GHSA-693p-m996-3rmf

https://github.com/vim/vim/commit/f209dcd3defb95bae21b2740910e6aa7bb940531

Co-authored-by: Christian Brabandt <cb@256bit.org>
Diffstat:
Mruntime/autoload/zip.vim | 6++++++
Atest/old/testdir/samples/poc.zip | 0
Mtest/old/testdir/test_plugin_zip.vim | 23+++++++++++++++++++++++
3 files changed, 29 insertions(+), 0 deletions(-)

diff --git a/runtime/autoload/zip.vim b/runtime/autoload/zip.vim @@ -14,6 +14,7 @@ " 2024 Aug 05 by Vim Project: clean-up and make it work with shellslash on Windows " 2024 Aug 18 by Vim Project: correctly handle special globbing chars " 2024 Aug 21 by Vim Project: simplify condition to detect MS-Windows +" 2025 Mar 11 by Vim Project: handle filenames with leading '-' correctly " 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, @@ -342,6 +343,11 @@ fun! zip#Extract() return endif let target = fname->substitute('\[', '[[]', 'g') + " unzip 6.0 does not support -- to denote end-of-arguments + " unzip 6.1 (2010) apparently supports, it, but hasn't been released + " so the workaround is to use glob '[-]' so that it won't be considered an argument + " else, it would be possible to use 'unzip -o <file.zip> '-d/tmp' to extract the whole archive + let target = target->substitute('^-', '[&]', '') if &shell =~ 'cmd' && has("win32") let target = target \ ->substitute('[?*]', '[&]', 'g') diff --git a/test/old/testdir/samples/poc.zip b/test/old/testdir/samples/poc.zip Binary files differ. diff --git a/test/old/testdir/test_plugin_zip.vim b/test/old/testdir/test_plugin_zip.vim @@ -235,3 +235,26 @@ func Test_zip_glob_fname() bw endfunc + +func Test_zip_fname_leading_hyphen() + CheckNotMSWindows + + "## copy sample zip file + if !filecopy("samples/poc.zip", "X.zip") + call assert_report("Can't copy samples/poc.zip") + return + endif + defer delete("X.zip") + defer delete('-d', 'rf') + defer delete('/tmp/pwned', 'rf') + + e X.zip + + :1 + let fname = '-d/tmp' + call search('\V' .. fname) + normal x + call assert_true(filereadable('-d/tmp')) + call assert_false(filereadable('/tmp/pwned')) + bw +endfunc