Arbitrary Code Execution via PHP Omni-Completion in Vim < 9.2.0736
==================================================================
Date: 28.06.2026
Severity: Medium
CVE: *requested, not yet assigned*
CWE: Improper Neutralization of Special Elements (CWE-94),
     Inclusion of Functionality from Untrusted Control Sphere (CWE-829)

## Summary
The PHP omni-completion script in `runtime/autoload/phpcomplete.vim`
interpolates a class or trait name, taken from the contents of the edited
buffer, into a `search()` pattern that is run via `win_execute()` without
escaping.  A name containing a single quote can terminate the `search()`
string argument early; because the bar (`|`) is honored as an Ex command
separator, the remainder of the name is then run as Ex commands.  Via the
`:!` command this allows arbitrary command execution.

## Description
`runtime/ftplugin/php.vim` installs `omnifunc=phpcomplete#Complete` on every
PHP buffer when Vim has filetype plugins enabled.  When the user invokes
omni-completion with `CTRL-X CTRL-O`, `phpcomplete#GetClassContentsStructure()`
locates a class declaration by building a `search()` command and running it
through `win_execute()`:

    call win_execute(popup_id,
      \ 'call search(''\c\(class\|interface\|trait\)\_s\+'
      \ .. a:class_name .. '\(\>\|$\)'')')

The class name is concatenated into the single-quoted `search()` argument
without neutralizing the single quote.  A `'` in the name ends that string
early, and the `:call` command honors the `EX_TRLBAR` attribute, so a bar
following the quote begins a new Ex command that `win_execute()` then runs.

The name passed to this function can originate from the buffer's own contents
(for example a class or trait name parsed from the file), so a crafted PHP
file can place an injecting value where a class name is expected.

## Impact
Arbitrary Ex command execution, and via the `:!` command arbitrary operating-
system command execution, in the context of the user running Vim.

Exploitation requires:

- Vim with filetype plugins enabled (`filetype plugin on`, the default in
  `runtime/defaults.vim` and most distribution `vimrc` files),
- the PHP omni-completion function in use
  (`omnifunc=phpcomplete#Complete`, set by the bundled PHP ftplugin),
- the victim opening a crafted PHP file and invoking omni-completion.

The severity is rated Medium because the user must open the crafted file and
manually invoke omni-completion; the bug does not fire on file-open alone.

## Acknowledgements
The Vim project would like to thank Hirohito Higashi for reporting, analyzing
and fixing the issue.

## References
The issue has been fixed as of Vim patch 
[v9.2.0736](https://github.com/vim/vim/releases/tag/v9.2.0736).
- 
[Commit](https://github.com/vim/vim/commit/43afc581a37a35762dd0ef292f038b9dc5680a24)
- [Github Security 
Advisory](https://github.com/vim/vim/security/advisories/GHSA-fh26-8f79-wj97)


Best,
Christian
-- 
Nur auf dem Boden harter Arbeit bereitet sich normalerweise der
Einfall vor.
                -- Max Weber

Reply via email to