patch 9.2.0357: [security]: command injection via backticks in tag files
Commit:
https://github.com/vim/vim/commit/c78194e41d5a0b05b0ddf383b6679b1503f977fb
Author: Christian Brabandt <
c...@256bit.org>
Date: Wed Apr 15 20:17:17 2026 +0000
patch 9.2.0357: [security]: command injection via backticks in tag files
Problem: [security]: command injection via backticks in tag files
(Srinivas Piskala Ganesh Babu, Andy Ngo)
Solution: Disallow backticks before attempting to expand filenames.
Github Advisory:
https://github.com/vim/vim/security/advisories/GHSA-cwgx-gcj7-6qh8
Supported by AI
Signed-off-by: Christian Brabandt <
c...@256bit.org>
diff --git a/src/tag.c b/src/tag.c
index d3e27e602..0f12e384b 100644
--- a/src/tag.c
+++ b/src/tag.c
@@ -4137,8 +4137,10 @@ expand_tag_fname(char_u *fname, char_u *tag_fname, int expand)
/*
* Expand file name (for environment variables) when needed.
+ * Disallow backticks, they could execute arbitrary shell
+ * commands. This is not needed for tag filenames.
*/
- if (expand && mch_has_wildcard(fname))
+ if (expand && mch_has_wildcard(fname) && vim_strchr(fname, '`') == NULL)
{
ExpandInit(&xpc);
xpc.xp_context = EXPAND_FILES;
diff --git a/src/testdir/test_tagjump.vim b/src/testdir/test_tagjump.vim
index bbab3c70e..c0fa7b02e 100644
--- a/src/testdir/test_tagjump.vim
+++ b/src/testdir/test_tagjump.vim
@@ -1693,4 +1693,26 @@ func Test_tag_excmd_with_number_vim9script()
bwipe!
endfunc
+" Test that backtick expressions in tag filenames are not expanded.
+" This prevents command injection via malicious tags files.
+func Test_tag_backtick_filename_not_expanded()
+ let pwned_file = 'Xtags_pwnd'
+ call assert_false(filereadable(pwned_file))
+
+ let tagline = "main `touch " .. pwned_file .. "` /^int main/;\" f"
+ call writefile([tagline], 'Xbt_tags', 'D')
+ call writefile(['int main(int argc, char **argv) {', '}'], 'Xbt_main.c', 'D')
+
+ set tags=Xbt_tags
+ sp Xbt_main.c
+
+ " The :tag command should fail to find the file, but must NOT execute
+ " the backtick shell command.
+ call assert_fails('tag main', 'E429:')
+ call assert_false(filereadable(pwned_file))
+
+ set tags&
+ bwipe!
+endfunc
+
" vim: shiftwidth=2 sts=2 expandtab
diff --git a/src/version.c b/src/version.c
index 0e22232f1..6716d470b 100644
--- a/src/version.c
+++ b/src/version.c
@@ -734,6 +734,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
+/**/
+ 357,
/**/
356,
/**/