macvim-dev / macvim-dev/macvim
[Security] MacVim affected by GHSA-crm5-rh6j-2c7c — netrw NetrwBookHistSave() code injection via crafted directory name (vim < 9.2.0495)
Dieses Issue hat noch niemand übernommen.
- Vorherrschende Sprache
- Vim Script
- Sterne
- 7.9k
- Forks
- 691
- PR-Merge-Kennzahlen
- Keine gemergten PRs in 30 T.
Beschreibung
[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 Details
- GHSA: GHSA-crm5-rh6j-2c7c
- Upstream fix: vim 9.2.0495 (commit
f08ab2f4d7d2947c8dd6c179ae08ee6146a2694b) - Affected code:
runtime/pack/dist/opt/netrw/autoload/netrw.vim—s:NetrwBookHistSave() - 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)
call setline(lastline,'let g:netrw_dirhist_'.cnt."='".g:netrw_dirhist_{cnt}."'")
This generates lines of the form:
let g: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:
let g:netrw_dirhist_1='x'|let g:injected=1|let y='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:mkdir -p "target/x'|call system('id > /tmp/pwned')|let y='z" - The victim opens this directory in netrw (
:Explore) inside MacVim and then quits vim. s:NetrwBookHistSave()writes the crafted path to~/.vim/.netrwhistunescaped.- The next time MacVim starts and opens netrw,
NetrwBookHistRead()sources.netrwhist,
executing the injectedcall 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)
call setline(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:
" Fixed (vim 9.2.0495):
call setline(lastline,'let g:netrw_dirhist_'.cnt.'='.string(g:netrw_dirhist_{cnt}))
string() produces a safely quoted Vimscript literal (e.g., "x'|cmd" for a path
containing '), so the value round-trips safely through source.
References
Beitragsleitfaden
Erste Schritte
- Lies das ganze Issue und danach den Beitragsleitfaden des Projekts.
- Schreib ins Issue, dass du es übernimmst — das erspart doppelte Arbeit.
- Forke das Repository und arbeite in einem Branch.
- Öffne einen Pull Request, der die Issue-Nummer nennt.
Rechercherichtung
Beginne mit runtime/pack/dist/opt/netrw/autoload/netrw.vim bei s:NetrwBookHistSave() und vergleiche es mit dem Upstream-Vim-Commit f08ab2f4d7d2947c8dd6c179ae08ee6146a2694b. Aktualisiere die gebündelte Runtime, erstelle anschließend MacVim und verifiziere, dass ein Verzeichnisname, der ein einfaches Anführungszeichen enthält, sicher gespeichert wird, ohne eingeschleustes Vimscript auszuführen.
Vom Indexierungsmodell aus dem Issue-Text verfasst.
Bewertung
- Tech-Stack
- vim
- Bereich
- security
- Issue-Typ
- Bug
- Schwierigkeit
- 2/5
- Geschätzter Aufwand
- Ein halber Tag
- Aktivitätsstatus
- Ruhig
- Klarheit
- Klar beschrieben
- Anfängerfreundlichkeit
- 72/100