fix(vim.secure): read() command injection vulnerability #39918

Problem:
Malicious filename can execute code because of ":" cmdline expansion.

Solution:
Use `fnameescape()`.

fix https://github.com/neovim/neovim/issues/39914
This commit is contained in:
Justin M. Keyes
2026-05-20 15:27:43 -04:00
committed by GitHub
parent 24e00f2844
commit 799cbfff85
2 changed files with 29 additions and 1 deletions

View File

@@ -268,6 +268,34 @@ describe('vim.secure', function()
-- Trust database is not updated
eq(nil, read_file(vim.fs.joinpath(stdpath('state'), 'trust')))
end)
it('(v)iew action does not execute malicious filename #39914', function()
if t.skip(t.is_os('win'), 'N/A: filename cannot have "|" char') then
return
end
local evil = 'Xfile|let g:secure_poc=42'
t.write_file(evil, 'pwned\n')
finally(function()
os.remove(evil)
end)
eq(
nil,
exec_lua(function(path)
vim.fn.confirm = function()
return 2 -- View
end
return vim.secure.read(path)
end, evil)
)
-- Malicious injected `:let` did NOT execute.
eq(0, fn.exists('g:secure_poc'))
-- The file is opened in a [RO] split with its literal name.
eq(true, api.nvim_get_option_value('readonly', {}))
eq(evil, vim.fs.basename(api.nvim_buf_get_name(0)))
end)
end)
describe('trust()', function()