VYPR
Medium severityNVD Advisory· Published Jun 11, 2026· Updated Jun 11, 2026

CVE-2026-47167

CVE-2026-47167

Description

A code injection in Vim's cucumber filetype plugin allows arbitrary Ruby execution via crafted step-definition patterns when a user opens a malicious repository.

AI Insight

LLM-synthesized narrative grounded in this CVE's description and references.

A code injection in Vim's cucumber filetype plugin allows arbitrary Ruby execution via crafted step-definition patterns when a user opens a malicious repository.

Vulnerability

A code injection vulnerability exists in s:stepmatch() within the cucumber filetype plugin (runtime/ftplugin/cucumber.vim) on Vim builds with +ruby support, prior to version 9.2.0496 [1]. Step-definition patterns read from .rb files under the repository's features/*/ or stories/*/ directories are embedded into a Ruby Kernel.eval argument without sufficient escaping [1]. The #{ guard rejects Ruby string-interpolation sequences but does not prevent the pattern from terminating the regex literal with / and appending arbitrary Ruby statements [1].

Exploitation

An attacker can place a crafted .rb file with a malicious step-definition pattern inside a repository's features/step_definitions/ or stories/ directory [1]. When a victim opens a .feature file in the same repository and invokes a step-jump mapping ([d or ]d), Vim's cucumber filetype plugin processes the step definitions and formats the pattern into a Ruby Kernel.eval call [1]. A pattern such as x/; system("touch marker"); #/ is evaluated by Ruby as a regex literal, a system() call, and a comment, executing the attacker's payload [1]. The attacker does not require any authentication beyond the ability to host a repository that the victim opens in Vim [1].

Impact

Successful exploitation allows the attacker to execute arbitrary Ruby code, and through it arbitrary shell commands, with the privileges of the user running Vim [1]. This can lead to full compromise of the user's system, including data exfiltration, malware installation, or further lateral movement [1]. The impact is limited to Vim builds with +ruby support and when the user opens a malicious repository [1].

Mitigation

The vulnerability has been patched in Vim version 9.2.0496, released on May 26, 2026 [2][3]. The fix replaces the Kernel.eval call with Regexp.new(), which treats the pattern as untrusted data and prevents code injection [2]. Users should update to Vim 9.2.0496 or later [2][3]. As a workaround, users can disable the cucumber filetype plugin by setting filetype plugin indent off or by removing +ruby support from their Vim build [1]. This CVE is not listed on CISA's Known Exploited Vulnerabilities (KEV) catalog as of the publication date [1].

AI Insight generated on Jun 11, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.

Affected products

2
  • Vim/Vimreferences2 versions
    (expand)+ 1 more
    • (no CPE)
    • (no CPE)range: <9.2.0496

Patches

1
a65a52d684bc

patch 9.2.0496: [security]: Code Injection in cucumber filetype plugin

https://github.com/vim/vimChristian BrabandtMay 17, 2026via nvd-ref
3 files changed · +36 1
  • runtime/ftplugin/cucumber.vim+4 1 modified
    @@ -2,6 +2,8 @@
     " Language:	Cucumber
     " Maintainer:	Tim Pope <vimNOSPAM@tpope.org>
     " Last Change:	2016 Aug 29
    +" 2026 May 26 by Vim Project: prevent Code Injection
    +" https://github.com/vim/vim/security/advisories/GHSA-4473-94jm-w5x9
     
     " Only do this when not done yet for this buffer
     if (exists("b:did_ftplugin"))
    @@ -96,7 +98,8 @@ function! s:stepmatch(receiver,target)
       catch
       endtry
       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}")
    +    " Use Regexp.new, so the pattern stays untrusted data and cannot inject Ruby
    +    ruby VIM.command("return #{if (begin; Regexp.new(VIM.evaluate('pattern')); rescue RegexpError; end) === VIM.evaluate('a:target') then 1 else 0 end}")
       else
         return 0
       endif
    
  • src/testdir/test_filetype.vim+30 0 modified
    @@ -3477,4 +3477,34 @@ func Test_app_file()
       filetype off
     endfunc
     
    +func Test_cucumber_code_injection()
    +  CheckFeature ruby
    +  filetype plugin on
    +
    +  call mkdir('Xcucu/features/step_definitions', 'pR')
    +  call writefile([
    +        \ 'Feature: demo',
    +        \ '  Scenario: trigger',
    +        \ '    Given xyzzy',
    +        \ ], 'Xcucu/features/test.feature')
    +  let marker = getcwd() . '/Xcucu/MARKER'
    +  " Malicious step: terminates the regex literal, injects Ruby system(),
    +  " comments the trailing slash.  With the fix, the pattern is passed to
    +  " Regexp.new() instead of Kernel.eval() and the payload is inert.
    +  call writefile([
    +        \ 'Given /xyzzy/; system("touch ' . marker . '"); #/ do',
    +        \ 'end',
    +        \ ], 'Xcucu/features/step_definitions/poc.rb')
    +
    +  new Xcucu/features/test.feature
    +  call assert_equal('cucumber', &filetype)
    +  call cursor(3, 1)
    +  " Triggers s:jump -> s:steps -> s:stepmatch on every discovered step,
    +  " including the malicious one.  Suppress preview and error messages.
    +  silent! normal [d
    +  call assert_false(filereadable(marker), 'Ruby injection executed')
    +  bwipe!
    +  filetype plugin off
    +endfunc
    +
     " vim: shiftwidth=2 sts=2 expandtab
    
  • src/version.c+2 0 modified
    @@ -729,6 +729,8 @@ static char *(features[]) =
     
     static int included_patches[] =
     {   /* Add new patch number below this line */
    +/**/
    +    496,
     /**/
         495,
     /**/
    

Vulnerability mechanics

Root cause

"The cucumber filetype plugin passes an untrusted step-definition pattern from a .rb file into Ruby's Kernel.eval() without escaping, allowing arbitrary code execution."

Attack vector

An attacker creates a malicious repository containing a Cucumber step-definition `.rb` file under `features/step_definitions/` (or `stories/`) with a crafted pattern that terminates the regex literal and injects arbitrary Ruby code, e.g. `Given /xyzzy/; system("touch ..."); #/ do`. When the victim opens a `.feature` file from that repository and presses `[d` or `]d` to jump to a step definition, Vim's cucumber filetype plugin reads the malicious pattern and passes it to `Kernel.eval()`, executing the injected Ruby and thereby arbitrary shell commands [CWE-94]. No authentication is required beyond opening the repository in Vim.

Affected code

The vulnerability resides in `runtime/ftplugin/cucumber.vim` in the `s:stepmatch()` function. The original code used `Kernel.eval('/'+VIM.evaluate('pattern')+'/')` to construct a Ruby regex from an untrusted step-definition pattern read from `.rb` files under `features/*/` or `stories/*/` directories. The patch replaces this with `Regexp.new(VIM.evaluate('pattern'))` to treat the pattern as data rather than executable code.

What the fix does

The patch replaces `Kernel.eval('/'+VIM.evaluate('pattern')+'/')` with `Regexp.new(VIM.evaluate('pattern'))` in `runtime/ftplugin/cucumber.vim`. The old code interpolated the untrusted pattern directly into a Ruby string that was then evaluated, allowing an attacker to break out of the regex literal and inject arbitrary Ruby. `Regexp.new()` treats its argument as a plain string pattern, so any embedded Ruby code is inert and simply becomes part of the regex syntax, preventing code injection. The test `Test_cucumber_code_injection()` confirms that a malicious pattern no longer executes a `system()` call.

Preconditions

  • configVim must be compiled with +ruby support.
  • inputThe user must open a .feature file from an attacker-controlled repository.
  • inputThe user must invoke the step-jump mapping ([d or ]d).

Generated on Jun 11, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.

References

3

News mentions

0

No linked articles in our index yet.