From 191a038d82f12d4d55a42c505bf3faa10c22fbe4 Mon Sep 17 00:00:00 2001 From: Christian Brabandt Date: Sun, 17 May 2026 18:53:48 +0000 Subject: [PATCH] patch 9.2.0495: [security]: runtime(netrw): code injection via NetrwBookHistSave() Problem: [security]: runtime(netrw): code injection via NetrwBookHistSave() Solution: Properly quote the directory name using string() function (Srinivas Piskala Ganesh Babu) Github Security Advisory: https://github.com/vim/vim/security/advisories/GHSA-crm5-rh6j-2c7c Signed-off-by: Christian Brabandt --- runtime/autoload/netrw.vim | 2 +- src/testdir/Make_all.mak | 2 ++ src/testdir/test_plugin_netrw.vim | 23 +++++++++++++++++++++++ 3 files changed, 26 insertions(+), 1 deletion(-) create mode 100644 src/testdir/test_plugin_netrw.vim diff --git a/runtime/autoload/netrw.vim b/runtime/autoload/netrw.vim index 47575ef90..f7a44f35c 100644 --- a/runtime/autoload/netrw.vim +++ b/runtime/autoload/netrw.vim @@ -3803,7 +3803,7 @@ fun! s:NetrwBookHistSave() while ( first || cnt != g:netrw_dirhistcnt ) let lastline= lastline + 1 if exists("g:netrw_dirhist_{cnt}") - call setline(lastline,'let g:netrw_dirhist_'.cnt."='".g:netrw_dirhist_{cnt}."'") + call setline(lastline,'let g:netrw_dirhist_'.cnt.'='.string(g:netrw_dirhist_{cnt})) " call Decho("..".lastline.'let g:netrw_dirhist_'.cnt."='".g:netrw_dirhist_{cnt}."'",'~'.expand("")) endif let first = 0 diff --git a/src/testdir/Make_all.mak b/src/testdir/Make_all.mak index 2b3d16d78..2ed089f98 100644 --- a/src/testdir/Make_all.mak +++ b/src/testdir/Make_all.mak @@ -229,6 +229,7 @@ NEW_TESTS = \ test_perl \ test_plugin_ccomplete \ + test_plugin_netrw \ test_plugin_phpcomplete \ test_plugin_tar \ test_plus_arg_edit \ test_popup \ @@ -482,6 +483,7 @@ NEW_TESTS_RES = \ test_perl.res \ test_plugin_ccomplete.res \ + test_plugin_netrw.res \ test_plugin_phpcomplete.res \ test_plugin_tar.res \ test_plus_arg_edit.res \ test_popup.res \ diff --git a/src/testdir/test_plugin_netrw.vim b/src/testdir/test_plugin_netrw.vim new file mode 100644 index 000000000..e9d771078 --- /dev/null +++ b/src/testdir/test_plugin_netrw.vim @@ -0,0 +1,23 @@ +" Tests for the netrw plugin + +func Test_netrw_injection() + let g:netrw_home = getcwd() + let savefile = g:netrw_home . '/.netrwhist' + let g:netrw_dirhistmax = 10 + let g:netrw_dirhistcnt = 1 + let g:netrw_dirhist_1 = "x'|let g:injected = 1|let y='z" + call delete(savefile) + try + call netrw#Call('NetrwBookHistSave') + call assert_true(filereadable(savefile), savefile . ' must be written') + unlet g:netrw_dirhist_1 + execute 'source ' . fnameescape(savefile) + call assert_false(exists("g:injected"), 'injected statement must not execute') + call assert_equal("x'|let g:injected = 1|let y='z", g:netrw_dirhist_1, 'dirname must round-trip') + finally + call delete(savefile) + unlet! g:netrw_home g:netrw_dirhistmax g:netrw_dirhistcnt g:netrw_dirhist_1 g:injected + endtry +endfunc + +" vim:ts=8 sts=2 sw=2 et