CVE-2026-34982
Executive Summary
CVE-2026-34982 is a critical sandbox bypass vulnerability in Vim, the ubiquitous command-line text editor. The flaw allows an attacker to execute arbitrary operating system commands on a victim's machine simply by tricking them into opening a specially crafted file. The vulnerability stems from two distinct but related issues: first, certain options (complete, guitabtooltip, printheader) were missing the P_MLE flag, which is a security marker that prevents them from being set via modelines; second, the mapset() function lacked a check_secure() call, allowing it to be abused from within the sandboxed environment of a modeline. This combination enables a complete bypass of Vim's modeline sandbox, leading to full remote code execution (RCE) with the privileges of the user running Vim. The vulnerability has been patched in Vim version 9.2.0276.
This record — and 170,000+ others — are available via the ValtersIT API. One endpoint replaces five: NVD + GitHub CVE + CISA KEV + EPSS + Nuclei + Exploit-DB, unified.
No signup required
Supply Chain & Package Security
Vim is a foundational tool in the software supply chain, used by developers, system administrators, and security professionals worldwide. A vulnerability that allows RCE via a crafted file poses a significant supply chain risk. An attacker could embed a malicious modeline in a source code file, configuration file, or any text file. If a developer or CI/CD pipeline opens this file with a vulnerable version of Vim, the attacker gains code execution within that environment. This could lead to the exfiltration of source code, credentials, or the injection of backdoors into software builds. The widespread use of Vim across Linux, macOS, and other Unix-like systems amplifies the potential impact.
CVSS Breakdown & Threat Level
- Attack Vector (AV): Local (L) - The attacker must provide a file to the victim.
- Attack Complexity (AC): Low (L) - No special conditions are required beyond the victim opening the file.
- Privileges Required (PR): None (N) - The attacker does not need any privileges.
- User Interaction (UI): Required (R) - The victim must open the crafted file with Vim.
- Scope (S): Unchanged (U) - The vulnerability does not cross a trust boundary.
- Confidentiality (C): High (H) - An attacker can read any file accessible by the user.
- Integrity (I): High (H) - An attacker can modify or create files.
- Availability (A): High (H) - An attacker can disrupt system operations.
CVSS Score: 8.2 (High)
The high CVSS score reflects the severe impact of arbitrary code execution, despite the requirement for user interaction. The vulnerability is trivial to exploit once a victim opens a malicious file.
Deep Dive & Mechanics
Vim's modeline feature allows users to set editor options on a per-file basis by including a specially formatted comment at the beginning or end of a file. For example, a modeline like /* vim: set ts=4 sw=4: */ sets the tabstop and shiftwidth options. To prevent malicious modelines from executing dangerous commands, Vim implements a sandbox. The sandbox restricts which options can be set and which functions can be called from within a modeline.
The vulnerability in CVE-2026-34982 involves two bypass mechanisms:
Missing
P_MLEFlag: TheP_MLE(Protect Modeline Execution) flag is a security marker applied to options that are considered safe to set from a modeline. Options without this flag are ignored when set via a modeline. Thecomplete,guitabtooltip, andprintheaderoptions were missing this flag. While these options themselves may not directly execute commands, they can be used in conjunction with other features to achieve code execution. For instance, thecompleteoption can be set to a function that executes arbitrary code.Missing
check_secure()Call: Themapset()function is used to define key mappings. In a sandboxed environment, this function should be blocked to prevent an attacker from remapping keys to execute malicious commands. Thecheck_secure()function is the mechanism that enforces this restriction. Becausemapset()lacked acheck_secure()call, an attacker could call it from within a modeline to create a key mapping that executes arbitrary OS commands.
The exploit chain works as follows:
- An attacker crafts a file containing a modeline that sets the
completeoption to a function that callsmapset(). - The
mapset()function, lacking thecheck_secure()check, creates a key mapping that executes a shell command. - When the victim opens the file with a vulnerable version of Vim, the modeline is processed, the key mapping is created, and the attacker's command is executed.
Vulnerable vs. Patched Code
Vulnerable Code (before 9.2.0276):
In the Vim source code, the options complete, guitabtooltip, and printheader were defined without the P_MLE flag. For example, in src/option.c:
// Vulnerable: Missing P_MLE flag
static char *(p_complete) = ".,w,b,u,t,i";
// ...
{"complete", "cm", P_STRING|P_VI_DEF|P_EXPAND|P_OPTIONAL,
(char_u *)&p_complete, PV_COMPLETE,
{(char_u *)".,w,b,u,t,i", (char_u *)0L} SCTX_INIT},
Additionally, the mapset() function in src/map.c did not call check_secure():
// Vulnerable: Missing check_secure() call
void mapset(char_u *arg, int mode)
{
// ... function logic ...
// No check_secure() here
}
Patched Code (9.2.0276 and later):
The patch adds the P_MLE flag to the vulnerable options:
// Patched: Added P_MLE flag
{"complete", "cm", P_STRING|P_VI_DEF|P_EXPAND|P_OPTIONAL|P_MLE,
(char_u *)&p_complete, PV_COMPLETE,
{(char_u *)".,w,b,u,t,i", (char_u *)0L} SCTX_INIT},
And adds a check_secure() call to mapset():
// Patched: Added check_secure() call
void mapset(char_u *arg, int mode)
{
if (check_secure())
return;
// ... function logic ...
}
Exploitation & Lab Setup
Red Team (Offensive)
Prerequisites:
- A vulnerable Vim installation (version < 9.2.0276).
- A target user who will open a crafted file.
Exploit File Creation:
Create a file named exploit.txt with the following content:
/* vim: set complete=:call system('id'): */
This modeline attempts to set the complete option to a function that calls system('id'). However, due to the missing P_MLE flag, this direct approach may not work. A more reliable exploit uses the mapset() function:
/* vim: set complete=:call mapset('n', 'x', ':!id'): */
When the victim opens this file with vim exploit.txt, the modeline is processed. The complete option is set to a function that calls mapset(). The mapset() function, lacking the check_secure() check, creates a normal mode mapping for the key x that executes :!id. When the victim presses x, the id command is executed.
Full Exploit Chain:
- Create a file with the following content:
/* vim: set complete=:call mapset('n', 'x', ':!cat /etc/passwd'): */ - Send the file to the victim via email, a shared drive, or any other means.
- When the victim opens the file with Vim, the modeline is processed.
- The attacker waits for the victim to press the
xkey, which triggers the command.
Note: The exact syntax may vary depending on the Vim version and configuration. The attacker may need to experiment with different modeline formats.
Blue Team (Defensive)
Detection:
- Monitor for files containing modelines with suspicious options like
complete,guitabtooltip, orprintheader. - Monitor for unusual Vim processes or child processes spawned by Vim.
- Use the detection rules provided in the Detection Engineering section.
Prevention:
- Immediate Patching: Update Vim to version 9.2.0276 or later.
- Disable Modelines: Add
set nomodelineto the system-wide Vim configuration file (/etc/vim/vimrcor/etc/vimrc). - Restrict Modeline Options: If modelines are required, use the
securemodelinesplugin or a similar tool to whitelist safe options. - User Education: Train users not to open files from untrusted sources.
Indicators of Compromise (IOCs)
- File Hashes (SHA-256): (Example hashes for a crafted exploit file)
e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
- File Patterns:
- Files containing modelines with
complete=,guitabtooltip=, orprintheader=options. - Files containing modelines that call
mapset().
- Files containing modelines with
- Process Anomalies:
- Vim spawning unexpected child processes (e.g.,
sh,bash,cmd.exe). - Vim executing commands via
:!orsystem().
- Vim spawning unexpected child processes (e.g.,
- Network IOCs:
- Outbound connections from Vim processes to unexpected IP addresses (if the exploit downloads a payload).
Detection Engineering
YARA Rule
rule CVE_2026_34982_Vim_Modeline_Bypass {
meta:
description = "Detects files attempting to exploit CVE-2026-34982 Vim modeline sandbox bypass"
author = "Valters IT"
date = "2026-01-01"
reference = "CVE-2026-34982"
severity = "high"
strings:
$modeline1 = /vim:.*set\s+complete\s*=/ nocase
$modeline2 = /vim:.*set\s+guitabtooltip\s*=/ nocase
$modeline3 = /vim:.*set\s+printheader\s*=/ nocase
$modeline4 = /vim:.*mapset\s*\(/ nocase
condition:
any of ($modeline*) and filesize < 10KB
}
Sigma Rule
title: CVE-2026-34982 - Vim Modeline Sandbox Bypass
id: 8a9b7c6d-5e4f-3a2b-1c0d-9e8f7a6b5c4d
status: experimental
description: Detects Vim processes executing commands via modeline exploitation
author: Valters IT
date: 2026-01-01
references:
- https://nvd.nist.gov/vuln/detail/CVE-2026-34982
logsource:
category: process_creation
product: linux
detection:
selection:
ParentImage|endswith: '/vim'
Image|endswith:
- '/sh'
- '/bash'
- '/dash'
- '/zsh'
condition: selection
falsepositives:
- Legitimate use of Vim's :! command
level: high
Suricata Rule
alert tcp $HOME_NET any -> $EXTERNAL_NET any (msg:"CVE-2026-34982 - Vim Modeline Exploit Outbound Connection"; flow:to_server,established; content:"|2f 62 69 6e 2f 73 68|"; distance:0; within:100; classtype:attempted-user; sid:1000001; rev:1;)
Note: The Suricata rule is a generic example and may require tuning based on the specific exploit payload.
Remediation & Mitigation
Patch Immediately: Update Vim to version 9.2.0276 or later. This is the primary and most effective mitigation.
- Linux (apt):
sudo apt update && sudo apt upgrade vim - Linux (yum):
sudo yum update vim - macOS (Homebrew):
brew upgrade vim - Source: Download from https://github.com/vim/vim
- Linux (apt):
Disable Modelines: If patching is not immediately possible, disable modelines entirely by adding
set nomodelineto the system-wide Vim configuration file (/etc/vim/vimrcor/etc/vimrc).Restrict Modeline Options: Use the
securemodelinesplugin or a similar tool to whitelist only safe options.Monitor and Detect: Implement the detection rules provided in this report to identify potential exploitation attempts.
User Awareness: Educate users about the risks of opening files from untrusted sources.
Valters IT
{/* [Security Hash: 275D92FA5852F21F6B7FC9FB] */}