Cheatsheet variable interpolation substitutes selected values into commands with no shell escaping, allowing injection via suggestion output
Summary
replace_variables_from_snippet (src/commands/core/actor.rs) splices a
selected variable's value directly into a snippet's command template
via plain string replacement (replacen), with no shell escaping. The
resulting string is then executed as <shell> -c <string>
(src/common/shell.rs out(), invoked from act in the same file).
A variable's value can come from a suggestion command declared in the
cheatsheet (a common, documented navi feature, e.g. $ file: ls), and
since file names on Linux impose essentially no character restriction,
a suggestion list built from file names can present the user with a
value that looks like an ordinary item to pick while containing shell
metacharacters. Selecting it injects those characters into the command
that runs.
Validated against the master branch tip (commit f7330b9).
POC
(available upon request)
Impact
I validated this by creating a minimal custom cheatsheet with a
$ file: ls <dir>-style suggestion, placing a file whose name was a
shell-metacharacter payload (x; touch navi_injection_poc; echo x) in
that directory, and driving navi interactively through selecting the
snippet and then that file suggestion. The output showed two separate
echo results rather than one line containing the full filename, and a
marker file created by the injected touch command was present
afterward, confirming full command execution, not just argument
injection.
Suggested Fix
Quote the resolved variable value appropriately for the target shell
(e.g. wrap in single quotes, escaping embedded single quotes) at the
point of substitution in replace_variables_from_snippet, rather than
splicing it into the command string as raw text.
Source: denisidoro/navi