[Security] MacVim affected by GHSA-crm5-rh6j-2c7c — netrw NetrwBookHistSave() code injection via crafted directory name (vim < 9.2.0495)

未关闭 适合新手
#1,653 0 条评论 0 个 reaction 已指派 0 人 在 GitHub 查看

还没有人认领这个 Issue。

评估

难度
2/5
预计耗时
半天
新手友好度
72/100
Issue 类型
缺陷
描述清晰度
描述清楚
活跃度
冷清
技术栈
vim
领域
security

调研方向

从 runtime/pack/dist/opt/netrw/autoload/netrw.vim 中的 s:NetrwBookHistSave() 开始,并将其与上游 Vim 提交 f08ab2f4d7d2947c8dd6c179ae08ee6146a2694b 进行比较。更新捆绑的 runtime,然后构建 MacVim,并验证包含单引号的目录名能够被安全持久化,而不会执行注入的 Vimscript。

由索引模型根据 Issue 内容生成。

描述

[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.vims: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
  1. 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"
    
  2. The victim opens this directory in netrw (:Explore) inside MacVim and then quits vim.
  3. s:NetrwBookHistSave() writes the crafted path to ~/.vim/.netrwhist unescaped.
  4. 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)
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

主要语言
Vim Script
星标
7.9k
派生
691
PR 合并指标
30 天内没有已合并 PR

贡献指南

打开贡献指南

从这里开始

  1. 先读完整个 Issue,再读项目的贡献指南。
  2. 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
  3. Fork 仓库,在一个分支上完成修改。
  4. 提交 Pull Request,并在描述里引用这个 Issue 编号。

macvim-dev/macvim 的其他 Issue

查看 macvim-dev/macvim 的全部 Issue

相似的 Issue

更多 Security Issue

把新 issue 发到你的邮箱

精选适合新手参与的 GitHub issue 摘要。