From 7088926316d8d4a7572a242d0765e99adfc8b083 Mon Sep 17 00:00:00 2001 From: Christian Brabandt Date: Wed, 1 Apr 2026 16:23:49 +0000 Subject: [PATCH] patch 9.2.0280: [security]: path traversal issue in zip.vim MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Problem: [security]: path traversal issue in zip.vim (MichaƂ Majchrowicz) Solution: Detect more such attacks and warn the user. Github Advisory: https://github.com/vim/vim/security/advisories/GHSA-jc86-w7vm-8p24 Signed-off-by: Christian Brabandt --- runtime/autoload/zip.vim | 8 +++++++- src/testdir/samples/evil.zip | Bin 148 -> 413 bytes src/testdir/test_plugin_zip.vim | 22 ++++++++++++++++++++++ src/version.c | 2 ++ 4 files changed, 31 insertions(+), 1 deletion(-) diff --git a/runtime/autoload/zip.vim b/runtime/autoload/zip.vim index e81308fac1..1ce9cfc2f7 100644 --- a/runtime/autoload/zip.vim +++ b/runtime/autoload/zip.vim @@ -20,6 +20,7 @@ " 2025 Dec 20 by Vim Project: use :lcd instead of :cd " 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 " 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, @@ -367,6 +368,11 @@ fun! zip#Write(fname) return endif + if simplify(a:fname) =~ '\.\.[/\\]' + call s:Mess('Error', "***error*** (zip#Write) Path Traversal Attack detected, not writing!") + return + endif + let curdir= getcwd() let tmpdir= tempname() if tmpdir =~ '\.' @@ -481,7 +487,7 @@ fun! zip#Extract() if fname =~ '/$' call s:Mess('Error', "***error*** (zip#Extract) Please specify a file, not a directory") return - elseif fname =~ '^[.]\?[.]/' + elseif fname =~ '^[.]\?[.]/' || simplify(fname) =~ '\.\.[/\\]' call s:Mess('Error', "***error*** (zip#Browse) Path Traversal Attack detected, not extracting!") return endif diff --git a/src/testdir/samples/evil.zip b/src/testdir/samples/evil.zip index e0a7f96141eed3ec5de68babd9d8bef7c72e5845..17cffadf934580090ebe2b3d3876edec14767658 100644 GIT binary patch literal 413 zcmWIWW@Zs#00E(lH&MUiHn*|?*&r+i#Cm%AaFkk-te;q+TTq?{M5!rU0YIHxKs5{u zPwN_E>VjErvI5y4?8G3$kciL-H-Q*NNp69DT7G^~Vo_)aCj;|c`?HxKTw1}+z{v7~ znSlXJfL##a&B!FejN9=br-8thMi7Z?Il?O-Gvt_Yc|!uEk%1A2w=`M-NoshC72+v0 V4+VI$g2J4E2?);s>D?d>0{|=}R4V`g delta 30 fcmbQsJcV(B&BVPfBCKo-K)?uuE" + normal x + assert_false(filereadable('/tmp/foobar')) + :w + var mess = execute(':mess') + assert_match('Path Traversal Attack', mess) + assert_match('zipfile://.*::.*tmp/foobar', @%) + bw! +enddef diff --git a/src/version.c b/src/version.c index 43fee673fb..2c47f0d722 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 */ +/**/ + 280, /**/ 279, /**/