[Security] MacVim affected by CVE-2026-43961 — netrw NetrwMarkFile() Vimscript injection via crafted filename (vim < 9.2.0480)
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.0480 that fixes CVE-2026-43961.
Vulnerability Details
- Upstream CVE: CVE-2026-43961
- Inherited from:
vim/vim
- Affected code:
runtime/autoload/netrw.vim — s:NetrwMarkFile() function
- Vulnerability type: CWE-94 — Improper Control of Generation of Code (Code Injection)
- Fixed in: vim 9.2.0480 (commit
8af0f098c3a42a28661d0295364e6e0fd7dbc92c)
Root Cause
In s:NetrwMarkFile() in runtime/autoload/netrw.vim, the global mark file list is
filtered using string interpolation of a user-controlled path:
" runtime/autoload/netrw.vim (macvim r183, line 5220)
let dname= netrw#fs#ComposePath(b:netrw_curdir,a:fname)
...
" remove new filename from global markfilelist
call filter(s:netrwmarkfilelist,'v:val != "'.dname.'"')
dname is composed from the current directory and the filename under the cursor (a:fname).
The filter() call evaluates its second argument as a Vimscript expression. Because dname
is interpolated directly into that expression string using '"'.dname.'"', a filename
containing a " character can escape the string context and inject arbitrary Vimscript.
Attack Scenario
- An attacker places a file named
foo"+system('id')+"bar in a directory.
- The victim opens that directory in netrw inside MacVim.
- The victim presses
mf to mark the file (adds it to the global mark list).
- The victim presses
mf again to unmark the file — this triggers line 5220.
- The
filter() call evaluates:
filter(s:netrwmarkfilelist, 'v:val != "foo"+system(''id'')+"bar"')
system('id') (or any arbitrary Vimscript/shell command) executes.
This can be triggered without any special permissions; any file accessible to the user
suffices. The attack is particularly relevant when opening untrusted project directories.
Affected MacVim Code
MacVim's runtime/pack/dist/opt/netrw/autoload/netrw.vim contains the vulnerable
s:NetrwMarkFile() function. The vulnerable line is:
" netrw.vim line 5220 (macvim r183)
call filter(s:netrwmarkfilelist,'v:val != "'.dname.'"')
Note: line 5179 (buffer-local list) uses 'v:val != a:fname' (variable reference, safe).
Only the global markfilelist at line 5220 is vulnerable.
The upstream fix (vim 9.2.0480) replaces the string interpolation with a lambda:
" Fixed form (vim >= 9.2.0480)
call filter(s:netrwmarkfilelist, {_, v -> v !=# dname})
The lambda form passes dname as a closed-over variable, never interpolating it into
an evaluated expression string.
neovim is NOT affected — its runtime/pack/dist/opt/netrw/autoload/netrw.vim already
uses the lambda form (lines 5167 and 5207).
Affected MacVim Version
MacVim r183 (vim 9.2 patches 1-321) — current HEAD as of 2026-05-18.
The fix commit 8af0f098c3a42a28661d0295364e6e0fd7dbc92c from vim/vim is not present
in the macvim-dev/macvim repository:
git log --all --oneline | grep 8af0f098 # returns no output
Suggested Fix
Merge or cherry-pick vim/vim patches up to at least 9.2.0480:
The fix changes the string-interpolated filter() expression to a lambda closure, which
avoids evaluating user-controlled data as Vimscript.
References
[Security] MacVim affected by CVE-2026-43961 — netrw NetrwMarkFile() Vimscript injection via crafted filename (vim < 9.2.0480)
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.0480 that fixes CVE-2026-43961.
Vulnerability Details
vim/vimruntime/autoload/netrw.vim—s:NetrwMarkFile()function8af0f098c3a42a28661d0295364e6e0fd7dbc92c)Root Cause
In
s:NetrwMarkFile()inruntime/autoload/netrw.vim, the global mark file list isfiltered using string interpolation of a user-controlled path:
dnameis composed from the current directory and the filename under the cursor (a:fname).The
filter()call evaluates its second argument as a Vimscript expression. Becausednameis interpolated directly into that expression string using
'"'.dname.'"', a filenamecontaining a
"character can escape the string context and inject arbitrary Vimscript.Attack Scenario
foo"+system('id')+"barin a directory.mfto mark the file (adds it to the global mark list).mfagain to unmark the file — this triggers line 5220.filter()call evaluates:system('id')(or any arbitrary Vimscript/shell command) executes.This can be triggered without any special permissions; any file accessible to the user
suffices. The attack is particularly relevant when opening untrusted project directories.
Affected MacVim Code
MacVim's
runtime/pack/dist/opt/netrw/autoload/netrw.vimcontains the vulnerables:NetrwMarkFile()function. The vulnerable line is:Note: line 5179 (buffer-local list) uses
'v:val != a:fname'(variable reference, safe).Only the global markfilelist at line 5220 is vulnerable.
The upstream fix (vim 9.2.0480) replaces the string interpolation with a lambda:
The lambda form passes
dnameas a closed-over variable, never interpolating it intoan evaluated expression string.
neovim is NOT affected — its
runtime/pack/dist/opt/netrw/autoload/netrw.vimalreadyuses the lambda form (lines 5167 and 5207).
Affected MacVim Version
MacVim r183 (vim 9.2 patches 1-321) — current HEAD as of 2026-05-18.
The fix commit
8af0f098c3a42a28661d0295364e6e0fd7dbc92cfromvim/vimis not presentin the
macvim-dev/macvimrepository:Suggested Fix
Merge or cherry-pick
vim/vimpatches up to at least 9.2.0480:The fix changes the string-interpolated
filter()expression to a lambda closure, whichavoids evaluating user-controlled data as Vimscript.
References