Skip to content

[Security] MacVim affected by VIM-9.2.0481 — netrw NetrwMaps() command injection via crafted directory names #1667

@dkgkdfg65

Description

@dkgkdfg65

[Security] MacVim affected by netrw command injection via crafted directory names in NetrwMaps() (vim < 9.2.0481)

Summary

MacVim bundles the vim source at version 9.2 (patches 1-321 in the current build), which is
below the patched version 9.2.0481 that fixes a command injection vulnerability in the
netrw plugin's s:NetrwMaps() function.

Vulnerability Details

  • Upstream fix: vim 9.2.0481 (commit 8e41c34aba0e775d2e3bf6f0e2da1b1c5317f3df)
  • Upstream CVE/GHSA: pending (no CVE assigned as of 2026-05-18)
  • Affected code: runtime/autoload/netrw.vims:NetrwMaps() function
  • Vulnerability type: CWE-94 — Improper Control of Generation of Code (Code Injection)

Root Cause

In s:NetrwMaps(), several buffer-local key maps are constructed dynamically using exe
with the current directory path interpolated into the command string:

" runtime/autoload/netrw.vim (macvim r183, lines 4943, 4959-4968)
let mapsafecurdir = escape(b:netrw_curdir, s:netrw_map_escape)
...
exe 'nnoremap <buffer> <silent> <nowait> <del> :call <SID>NetrwLocalRm("'.mapsafecurdir.'")<cr>'
exe 'nnoremap <buffer> <silent> <nowait> D     :call <SID>NetrwLocalRm("'.mapsafecurdir.'")<cr>'
exe 'nnoremap <buffer> <silent> <nowait> R     :call <SID>NetrwLocalRename("'.mapsafecurdir.'")<cr>'

The escape set (s:netrw_map_escape = "<|\n\r\\\<C-V>\") escapes backslash before
< characters, turning them into \<. However, with the B flag set in cpo (the
default), \<CR> in the RHS of a mapping is interpreted as an actual Enter keystroke
rather than the literal two-character sequence \<CR>.

An attacker who can create a directory named with a <CR> (four literal characters
<, C, R, >) followed by Vimscript commands can cause those commands to execute
when the victim opens that directory in netrw and triggers any of the D, R, or
<Del> maps.

Attack Scenario

  1. An attacker creates a directory named:
    /path/to/evil<CR>:let g:pwned=1<CR>
    
    (where <CR> represents the four literal characters <, C, R, >)
  2. The victim opens this directory in netrw inside MacVim (e.g., via :Explore).
  3. s:NetrwMaps() constructs the D map with the path interpolated; escape() turns
    < into \<, yielding \<CR>:let g:pwned=1\<CR> in the RHS.
  4. With cpo containing the B flag (default), \<CR> in the map RHS is interpreted
    as actual Enter. The map fires :call NetrwLocalRm("evil, then Enter, then
    :let g:pwned=1, then Enter — executing injected Vimscript.
  5. Any user keystroke of D, R, or <Del> while browsing the directory triggers
    the injected commands.

Affected MacVim Code

" netrw.vim line 4943 (macvim r183)
let mapsafecurdir = escape(b:netrw_curdir, s:netrw_map_escape)

The escape() call does not protect against <CR> (four-character angle-bracket
notation) because the B flag in cpo makes the map interpreter expand \<CR> to
actual Enter.

Affected MacVim Version

MacVim r183 (vim 9.2 patches 1-321) — current HEAD as of 2026-05-18.

The fix commit 8e41c34aba0e775d2e3bf6f0e2da1b1c5317f3df from vim/vim is not present
in the macvim-dev/macvim repository:

git log --all --oneline | grep 8e41c34a  # returns no output

Suggested Fix

Merge or cherry-pick vim/vim patches up to at least 9.2.0481:

The fix adds a save/restore of cpo with B temporarily removed at the start of
s:NetrwMaps(), preventing \<CR> in interpolated paths from being treated as actual
Enter keystrokes:

function s:NetrwMaps(islocal)
    let _cpo = &cpo
    set cpo-=B
    " ... map construction ...
    let &cpo = _cpo
endfunction

References

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions