Opened 4 weeks ago

Closed 10 days ago

#5928 closed enhancement (fixed)

vim-9.2.0481 (Security Update)

Reported by: Joe Locash Owned by: SecurityAdvisory
Priority: high Milestone: 13.1
Component: Book Version: git
Severity: normal Keywords:
Cc:

Description

OS Command Injection via 'path' completion affects Vim < 9.2.0435
=================================================================
Date: 02.05.2026
Severity: Medium
CVE: *requested, not yet assigned*
CWE: Improper Neutralization of Special Elements used in an OS Command ('OS Command Injection') (CWE-78)

## Summary
An OS command injection vulnerability exists in Vim's `:find`
command-line completion.  When the `path` option contains
backtick-enclosed shell commands, those commands are executed during
file name completion. Because the `path` option lacks the `P_SECURE`
flag, it can be set from a modeline, allowing an attacker who controls
the contents of a file to execute arbitrary shell commands when the user
opens that file in Vim and triggers `:find` completion.

## Description
The `path` option is used by `:find` Ex commands to locate files.  When
command-completion is invoked on these commands, the value of `path` is
processed by `expand_in_path()`, which ultimately reaches
`mch_expand_wildcards()`.  The latter constructs a shell command from
each path entry and any matching glob characters; in the process, text
enclosed in backticks is executed by the shell.

The `expand_in_path()` code path has no check for backtick expansion.
Additionally, the `path` option is missing the `P_SECURE` flag in
`optiondefs.h`, so a modeline can set it to a value containing
backticks.  Once the modeline has been applied, the `secure` global is
no longer set, and the subsequent `:find` completion executes the
backtick contents.

## Impact
The vulnerability allows arbitrary shell command execution in the
context of the Vim process when the user invokes `:find`, `:sfind`,
`:tabfind` or related completion and the path option has been set to
include backticks.

Exploitation via modeline requires `'modeline'` to be enabled (the
default in Vim <9.2.0350) and the user to trigger file completion after
opening the file.

The severity is rated Medium because exploitation requires opening an
attacker-controlled file and pressing Tab during a common completion
operation.

Vim 9.2.0350 and later are not affected from the modeline vulnerability
because the `'modelinestrict'` hardening prevents `'path'` from being
set via modeline.

## Acknowledgements
The Vim project would like to thank github user @q1uf3ng for reporting
the issue.

## References
The issue has been fixed as of Vim patch [v9.2.0435](https://github.com/vim/vim/releases/tag/v9.2.0435).
- [Commit](https://github.com/vim/vim/commit/190cb3c2b9c769a3972bcfd991a7b5b6cb771ef0)
- [Github Security Advisory](https://github.com/vim/vim/security/advisories/GHSA-hwg5-3cxw-wvvg)

Change History (8)

comment:1 by Joe Locash, 4 weeks ago

Summary: Vim => v9.2.0435 (Security Update)Vim => v9.2.0450 (Security Update)
Heap Buffer Overflow in spell file loading affects Vim < 9.2.0450
=================================================================
Date: 07.05.2026
Severity: Medium
CVE: *requested, not yet assigned*
CWE: Integer Overflow or Wraparound (CWE-190) leading to Heap-based Buffer Overflow (CWE-122)

## Summary
A heap buffer overflow exists in `read_compound()` in `src/spellfile.c`
when loading a crafted spell file (`.spl`) with UTF-8 encoding active.
An attacker-controlled length field in the spell file's compound section
overflows a 32-bit signed integer multiplication, causing a small buffer
to be allocated for a write loop that runs many iterations, overflowing
the heap.  Because the `'spelllang'` option can be set from a modeline,
a text file modeline can trigger spell file loading if a malicious
`.spl` file has been planted on the runtimepath.

## Description
In `read_compound()` (`src/spellfile.c`), the buffer size for the regex
pattern `pat` is computed from the attacker-controlled `sectionlen`
field of an `SN_COMPOUND` section.  Both `todo` and the size variable
`c` are declared as `int`:

    c = todo * 2 + 7;
    if (enc_utf8)
        c += todo * 2;
    pat = alloc(c);

When `todo` is sufficiently large (e.g. `0x40000005`), the multiplication
`todo * 4 + 7` overflows the 32-bit signed integer and wraps to a small
positive value (e.g. 27).  `alloc(27)` succeeds, but the subsequent loop
iterates `todo` (~1 billion) times, writing bytes into the 27-byte
buffer and corrupting adjacent heap memory.

The overflow only manifests when UTF-8 encoding is active (`enc_utf8`).
Without it, the intermediate value remains negative, sign-extends to a
huge `size_t`, and `alloc()` returns NULL harmlessly.  UTF-8 is the
default on virtually all modern Linux and macOS systems.

A modeline in an unrelated text file can set `'spelllang'` and enable
`'spell'`, causing Vim to load a spell file under the attacker's control
if one has been planted on the runtimepath (e.g. `~/.vim/spell/`).

## Impact
The vulnerability allows a heap buffer overflow of approximately 75
bytes with partially attacker-controlled content when Vim loads a
crafted spell file under UTF-8 encoding.  The practical impact is a
crash of the Vim process (denial of service).

Exploitation requires a malicious `.spl` file to be present on the
runtimepath and the victim to either:

- explicitly enable spell checking with the matching language, or
- open any text file containing a modeline that sets `'spelllang'`
  and enables `'spell'`, while `'modeline'` is enabled.

The severity is rated Medium because exploitation requires both a
planted spell file and a separate triggering action by the victim, and
the practical outcome is a crash rather than code execution.

## Acknowledgements
The Vim project would like to thank Daniel Cervera (@daniel-msft) of
Microsoft Security Engineering for reporting and analyzing the issue and
suggesting a fix.

## References
The issue has been fixed as of Vim patch [v9.2.0450](https://github.com/vim/vim/releases/tag/v9.2.0450).
- [Commit](https://github.com/vim/vim/commit/92993329178cb1f72d700fff45ca86e1c2d369f8)
- [Github Security Advisory](https://github.com/vim/vim/security/advisories/GHSA-q4jv-r9gj-6cwv)

comment:2 by Bruce Dubbs, 3 weeks ago

Summary: Vim => v9.2.0450 (Security Update)vim => v9.2.0450 (Security Update)

comment:3 by Bruce Dubbs, 3 weeks ago

Owner: changed from lfs-book to SecurityAdvisory

Fixed at commit 6d990d4871. Leaving open for security advisory.

comment:4 by Douglas R. Reno, 3 weeks ago

Owner: changed from SecurityAdvisory to lfs-book
Summary: vim => v9.2.0450 (Security Update)vim => v9.2.0480 (Security Update)

We're going to want to update this again to account for two new VIM security advisories that went public today:

Command Injection in tar.vim affects Vim < 9.2.479
==================================================
Date: 14.05.2026
Severity: Medium
CVE: *requested, not yet assigned*
CWE: Improper Neutralization of Special Elements used in an OS Command (CWE-78) /
     Improper Neutralization of Argument Delimiters in a Command (CWE-88)

## Summary
A command injection vulnerability exists in `tar#Vimuntar()` in
`runtime/autoload/tar.vim` when decompressing `.tgz` archives on
Unix-like systems.  The function builds `:!gunzip` and `:!gzip -d`
commands using `shellescape(tartail)` without the `{special}` flag,
allowing a crafted archive filename to trigger Vim cmdline-special
expansion and execute shell commands in the user's context.

## Description
In `tar#Vimuntar()` (`runtime/autoload/tar.vim`), the archive tail name
derived from the current buffer filename is incorporated into a `:!`
command via `shellescape()` without the second argument.  For `:!`
commands, Vim re-expands cmdline-special characters (`%`, `#`, `!`, and
similar) before passing the command to the shell.  As documented under
`:help shellescape()`, the second argument must be set to a non-zero
value (`shellescape({string}, 1)`) whenever the result is used inside
`:!` or `:r !`.  Because the flag is omitted here, a filename containing
both shell metacharacters and Vim special characters can break out of
the intended single-quoted argument and inject arbitrary shell commands.

## Impact
The vulnerability allows arbitrary shell command execution with the
privileges of the user running Vim.  Exploitation requires:
- a Unix-like system with the tar plugin enabled,
- a crafted `.tgz` archive on disk whose filename contains both a
  single quote and Vim cmdline-special characters, and
- the victim to open the file and invoke the non-routine `:Vimuntar`
  command.
The severity is rated Medium because successful exploitation yields
arbitrary command execution, but the requirement for a user-initiated
`:Vimuntar` invocation on an attacker-supplied suspicious filename limits the
practical attack surface.

## Acknowledgements
The Vim project would like to thank Aisle Research for reporting and
analyzing the issue.

## References
The issue has been fixed as of Vim patch [v9.2.479](https://github.com/vim/vim/releases/tag/v9.2.0479).
- [Commit](https://github.com/vim/vim/commit/3fb5e58fbc63d86a3e65f1a141b0d67af2aa38a1)
- [Github Security Advisory](https://github.com/vim/vim/security/advisories/GHSA-2fpv-9ff7-xg5w)

and

Vimscript Code Injection in netrw NetrwMarkFile() via crafted filename affects Vim < 9.2.480
============================================================================================
Date: 14.05.2026
Severity: Medium
CVE: CVE-2026-43961
CWE: Improper Control of Generation of Code (CWE-94) /
     Improper Neutralization of Special Elements in Output Used by a Downstream Component (CWE-74)

## Summary
A Vimscript code injection vulnerability exists in `s:NetrwMarkFile()` in the
netrw plugin (`runtime/pack/dist/opt/netrw/autoload/netrw.vim`) when
unmarking files from the global marked-file list.  A filename derived
from the buffer's directory listing is interpolated into a string
expression passed to `filter()`, allowing a crafted filename containing
a double quote to break out of the quoted string literal and execute
arbitrary Vimscript, including shell commands via `execute()` and `:!`.

## Description
`s:NetrwMarkFile()` maintains two marked-file lists: a buffer-local list
and a global list.  When a file is unmarked, both lists are updated.
The buffer-local list uses the safe pattern:

    call filter(s:netrwmarkfilelist_{curbufnr},'v:val != a:fname')

where `a:fname` is referenced as a variable inside the filter expression
and resolved at evaluation time.  The global list, however, interpolated
the filename's value directly into the expression string:

    let dname = netrw#fs#ComposePath(b:netrw_curdir, a:fname)
    ...
    call filter(s:netrwmarkfilelist, 'v:val != "'.dname.'"')

When `filter()` receives a string argument, the string is parsed as a
Vimscript expression.  A filename containing `"` terminates the quoted
literal early, after which the remainder of the filename is evaluated as
Vimscript.  Calls such as `execute("!cmd")` inside the injected fragment
run arbitrary Ex commands with the privileges of the user running Vim.
The filename reaches `s:NetrwMarkFile()` through the `mf` mapping, which
calls `s:NetrwGetWord()` to read the filename from the current line of
the netrw directory listing.  The injection only triggers on the second
`mf` press for a given entry, because the first press takes the
`add()` branch and only the second takes the vulnerable `filter()`
branch.

## Impact
The vulnerability allows arbitrary Vimscript execution, and by extension
arbitrary shell command execution, with the privileges of the user
running Vim.  Exploitation requires:
- a Unix-like system on which a filename may contain a double quote,
- a crafted file present in a directory the victim browses with netrw,
  and
- the victim to invoke `mf` twice on that specific entry to mark and
  then unmark it.
The severity is rated Medium because exploitation requires a planted
file with an unusual name and a deliberate mark/unmark action by the
victim on that specific entry, although the resulting primitive is full
command execution as the victim user.

Note: due to the nature of the issue, it seems highly unlikely that a user
would press mf twice on such a suspicious filename.

## Acknowledgements
The Vim project would like to thank Aisle Research for reporting and
analyzing the issue.

## References
The issue has been fixed as of Vim patch [v9.2.480](https://github.com/vim/vim/releases/tag/v9.2.0480).
- [Commit](https://github.com/vim/vim/commit/8af0f098c3a42a28661d0295364e)
- [Github Security Advisory](https://github.com/vim/vim/security/advisories/GHSA-66hr-7p6x-x5j3)

comment:5 by Douglas R. Reno, 3 weeks ago

Summary: vim => v9.2.0480 (Security Update)vim-9.2.0481 (Security Update)

comment:7 by Douglas R. Reno, 3 weeks ago

Owner: changed from lfs-book to SecurityAdvisory

Holding open for security advisory.

comment:8 by Douglas R. Reno, 10 days ago

Resolution: fixed
Status: newclosed

SA-13.0-071 issued

Note: See TracTickets for help on using tickets.