You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
[Security] MacVim affected by GHSA-crm5-rh6j-2c7c — netrw NetrwBookHistSave() code injection via crafted directory name (vim < 9.2.0495) #1653
[Security] MacVim affected by GHSA-crm5-rh6j-2c7c — netrw NetrwBookHistSave() code injection via crafted directory name (vim < 9.2.0495)
Summary
MacVim bundles the vim runtime at version 9.2 (patches 1-321 in the current build), which is
below the patched version 9.2.0495 that fixes a code injection vulnerability in the netrw
plugin's s:NetrwBookHistSave() function.
Vulnerability type: CWE-94 — Improper Control of Generation of Code (Code Injection)
Root Cause
In s:NetrwBookHistSave(), the directory history is serialized to ~/.vim/.netrwhist using
a single-quoted Vimscript string literal without escaping embedded single quotes:
" runtime/pack/dist/opt/netrw/autoload/netrw.vim line 2961 (macvim r183)callsetline(lastline,'let g:netrw_dirhist_'.cnt."='".g:netrw_dirhist_{cnt}."'")
This generates lines of the form:
letg:netrw_dirhist_1='/some/path'
If the directory name (stored in g:netrw_dirhist_{cnt}) contains a single quote ', the
generated Vimscript breaks out of the string literal. For example, a directory named:
x'|let g:injected=1|let y='z
would generate:
letg:netrw_dirhist_1='x'|letg:injected=1|lety='z'
When ~/.vim/.netrwhist is later sourced by netrw (at vim startup via the VimLeave
autocommand that calls NetrwBookHistRead), the injected Vimscript executes.
Attack Scenario
An attacker creates a directory named with an embedded single-quote followed by
Vimscript commands:
The victim opens this directory in netrw (:Explore) inside MacVim and then quits vim.
s:NetrwBookHistSave() writes the crafted path to ~/.vim/.netrwhist unescaped.
The next time MacVim starts and opens netrw, NetrwBookHistRead() sources .netrwhist,
executing the injected call system('id > /tmp/pwned') command.
This provides persistent arbitrary command execution — the payload is written once and
fires on every subsequent vim startup.
Affected MacVim Code
" netrw.vim line 2961 (macvim r183)callsetline(lastline,'let g:netrw_dirhist_'.cnt."='".g:netrw_dirhist_{cnt}."'")
The directory path g:netrw_dirhist_{cnt} is interpolated directly into a single-quoted
string without any escaping.
Affected MacVim Version
MacVim r183 (vim 9.2 patches 1-321) — current HEAD as of 2026-05-18.
The fix commit f08ab2f4d7d2947c8dd6c179ae08ee6146a2694b from vim/vim is not present
in the macvim-dev/macvim repository.
Suggested Fix
Merge or cherry-pick vim/vim patches up to at least 9.2.0495.
The fix replaces the unescaped string interpolation with Vimscript's built-in string()
function, which properly double-quotes the value and escapes embedded single quotes:
Activity