Commit: patch 9.2.0481: runtime(netrw): command injection possible via maps

4 views
Skip to first unread message

Christian Brabandt

unread,
May 14, 2026, 3:00:12 PM (22 hours ago) May 14
to vim...@googlegroups.com
patch 9.2.0481: runtime(netrw): command injection possible via maps

Commit: https://github.com/vim/vim/commit/8e41c34aba0e775d2e3bf6f0e2da1b1c5317f3df
Author: Christian Brabandt <c...@256bit.org>
Date: Thu May 14 18:46:56 2026 +0000

patch 9.2.0481: runtime(netrw): command injection possible via maps

Problem: runtime(netrw): command injection possible via crafted
directory names in NetrwMaps() (Christopher Lusk)
Solution: Temporarily remove B flag in NetrwMaps() to prevent command
injection

Signed-off-by: Christian Brabandt <c...@256bit.org>

diff --git a/runtime/pack/dist/opt/netrw/autoload/netrw.vim b/runtime/pack/dist/opt/netrw/autoload/netrw.vim
index 8681091f0..176cdcb87 100644
--- a/runtime/pack/dist/opt/netrw/autoload/netrw.vim
+++ b/runtime/pack/dist/opt/netrw/autoload/netrw.vim
@@ -4810,6 +4810,12 @@ endfunction

" s:NetrwMaps: {{{2
function s:NetrwMaps(islocal)
+ " remove B flag from 'cpo' so that \<CR>, \<Bar>, etc. inside
+ " interpolated path names play back as literal text rather than
+ " the actual key — without this, a crafted directory name can
+ " inject keystrokes into the cmdline the mapping is typing
+ let _cpo = &cpo
+ set cpo-=B

" mouse <Plug> maps: {{{3
if g:netrw_mousemaps && g:netrw_retmap
@@ -5054,6 +5060,7 @@ function s:NetrwMaps(islocal)
" support user-specified maps
call netrw#UserMaps(0)
endif " }}}3
+ let &cpo = _cpo
endfunction

" s:NetrwCommands: set up commands {{{2
diff --git a/src/testdir/test_plugin_netrw.vim b/src/testdir/test_plugin_netrw.vim
index 72bf8300e..4256dc9d2 100644
--- a/src/testdir/test_plugin_netrw.vim
+++ b/src/testdir/test_plugin_netrw.vim
@@ -731,6 +731,7 @@ func Test_netrw_mf_command_injection()
let path = tempname()
let fname = 'x" . execute("silent! !touch poc") . "'
call mkdir(path, 'R')
+ let _cwd = getcwd()
exe "cd " path
call writefile([], fname)
Explore .
@@ -738,6 +739,25 @@ func Test_netrw_mf_command_injection()
:norm mf
:norm mf
call assert_false(filereadable('poc'), 'Command injection via mf command')
+ exe "cd " _cwd
+ bw!
endfunc

+function Test_netrw_NetrwMaps_CR_dirname()
+ CheckNotMSWindows
+
+ let tmpdir = tempname() . '/evil<CR>:let g:netrw_pwn=1<CR>'
+ call mkdir(tmpdir, 'pR')
+ call assert_true(isdirectory(tmpdir))
+ exe ":Explore " tmpdir
+ " Fire D
+ " If the commands are injected successfully,
+ " this fails with
+ " Vim(let):E488: Trailing characters: \ @ command line script
+ call feedkeys("D\<C-c>\<C-c>", "xt")
+ call assert_false(exists("g:netrw_pwn"))
+
+ unlet! g:netrw_pwn
+ bw!
+endfunction
" vim:ts=8 sts=2 sw=2 et
diff --git a/src/version.c b/src/version.c
index df580d3de..10a787cac 100644
--- a/src/version.c
+++ b/src/version.c
@@ -729,6 +729,8 @@ static char *(features[]) =

static int included_patches[] =
{ /* Add new patch number below this line */
+/**/
+ 481,
/**/
480,
/**/
Reply all
Reply to author
Forward
0 new messages