]> git.ipfire.org Git - thirdparty/vim.git/commitdiff
patch 9.2.0495: [security]: runtime(netrw): code injection via NetrwBookHistSave() v9.2.0495
authorChristian Brabandt <cb@256bit.org>
Sun, 17 May 2026 18:53:48 +0000 (18:53 +0000)
committerChristian Brabandt <cb@256bit.org>
Sun, 17 May 2026 18:53:48 +0000 (18:53 +0000)
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 <cb@256bit.org>
runtime/pack/dist/opt/netrw/autoload/netrw.vim
src/testdir/test_plugin_netrw.vim
src/version.c

index 176cdcb87f9fadbd46139b69fd9db68903ec998e..1fdbeeb8f799f2f0a0421156f7bb24df52c9bb26 100644 (file)
@@ -1,7 +1,7 @@
 " Creator:    Charles E Campbell
 " Previous Maintainer: Luca Saccarola <github.e41mv@aleeas.com>
 " Maintainer: This runtime file is looking for a new maintainer.
-" Last Change: 2026 May 14
+" Last Change: 2026 May 17
 " Copyright:  Copyright (C) 2016 Charles E. Campbell {{{1
 "             Permission is hereby granted to use and distribute this code,
 "             with or without modifications, provided that this copyright
@@ -2935,7 +2935,7 @@ function 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}))
             endif
             let first   = 0
             let cnt     = ( cnt - 1 ) % g:netrw_dirhistmax
index 4256dc9d2a6e2e2c2b5b965b8a1f4acde41c70cb..7cd2aa89ed642852f26b0879087b89692e641512 100644 (file)
@@ -760,4 +760,24 @@ function Test_netrw_NetrwMaps_CR_dirname()
   unlet! g:netrw_pwn
   bw!
 endfunction
+
+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
index f6e20cfa0745043980e3d09d65addd13b843fb79..0a9e8190635f2f30a98beaa6e902c34896fe9c2a 100644 (file)
@@ -729,6 +729,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    495,
 /**/
     494,
 /**/