GHSA-52mc-rq6p-rc7c on CTRL-OS 26.05
Aliases: GHSA-52mc-rq6p-rc7c, CVE-2026-52858
Packages: vim
Status: Plausible
Advisory Information
Arbitrary Code Execution via Python Omni-Completion in Vim < 9.2.561
Date: 29.05.2026 Severity: Medium CVE: CVE-2026-52858 CWE: Improper Control of Generation of Code (CWE-94), Inclusion of Functionality from Untrusted Control Sphere (CWE-829)
Summary
The Python omni-completion script in
python3complete.vimfor Vim with the+python3interpreter enabled (and the legacypythoncomplete.vimfor builds with the+pythoninterpreter) executes theimportandfromstatements found in the current buffer through Python's import machinery. Because the buffer's working directory is onsys.path, opening a hostile.pyfile with a sibling Python package and invoking omni-completion runs that package's top-level code as the editing user.Description
runtime/ftplugin/python.viminstallsomnifunc=python3complete#Completeon every Python buffer when Vim has+python3(or+python). When the user invokes omni-completion withCTRL-X CTRL-Oin insert mode, the completer parses the buffer with an embedded Python tokenizer, regenerates a Python source string from the parsed scope, and passes it toexec(src, self.compldict)to populate the completion dictionary.The regenerated source re-emits every top-level
import Xandfrom X import Ystatement that the parser harvested from the buffer. Additionally, the completer extendssys.pathwith['.', '..']so that sibling modules in the buffer's working directory are importable. The combined effect: invoking omni-completion on a.pyfile runs Python's import machinery on attacker-supplied module names with the attacker's working directory on the search path.A crafted
.pyfile containingimport evil_pkgand a siblingevil_pkg/__init__.pyin the same directory will execute the__init__.pycode when the victim opens the file and pressesCTRL-X CTRL-O.Impact
Arbitrary local code execution as the user running Vim, with the user's full credential set (SSH keys, cloud credentials, etc.), file-system access, and network egress. Realistic delivery vectors include:
- reviewing a third-party Python contribution by checking out a fork branch and opening any
.pyfile in it,- auditing an extracted source tarball, malware sample, or repository whose layout the attacker controls,
- opening a
.pyfile from any downloaded archive where the extracted layout places a hostile package next to the file being inspected.Exploitation requires:
- Vim built with
+python3(or+python3/dynwith a working Python 3 runtime)- Filetype plugins enabled (
filetype plugin on, the default inruntime/defaults.vimand most distributionvimrcs).- The victim opens the hostile
.pyfile from the attacker-controlled working directory and invokes omni-completion.The severity is rated Medium because the user must manually invoke omni- completion after opening the file; the bug does not fire on file-open alone.
Mitigation
As of Vim patch v9.2.0561 the omni-completer no longer executes
importorfromstatements harvested from the buffer by default. Users who require completion of imported module members (for exampleos.<C-X><C-O>offeringgetcwd,path, etc.) can opt back in with: >let g:pythoncomplete_allow_import = 1
Setting this variable re-enables the import-execution behavior and should only be used when editing code from trusted sources. When the variable is unset or
0, in-buffer symbols (classes, functions, variables defined in the file) still complete normally; only completion of names that would require executing imports is unavailable.Acknowledgements
The Vim project would like to thank github user tonghuaroot for reporting, analyzing the issue, providing a proof of concept and suggesting a fix.
References
The issue has been fixed as of Vim patch v9.2.0561. - Commit - Github Security Advisory
Updates
2026-07-10 22:52 CEST
Metadata changes:
- Status for package
vim: “Plausible”
2026-06-26 14:39 CEST
Metadata changes:
- Status for package
vim: “New”
(Amended on: 2026-07-10 22:52 CEST)