Problem
hooks/lib/tab-setter.ts uses execSync() with string interpolation to build shell commands:
execSync(`kitten @ --to="${kittyEnv.listenOn}" set-tab-title "${escaped}"`, ...)
This is vulnerable to command injection if KITTY_LISTEN_ON or the tab title contains shell metacharacters. The escaped variable only escapes double quotes, not backticks, $(), semicolons, or other shell operators.
The same pattern appears in cleanupStaleStateFiles() which also pipes through jq, adding another injection surface.
Impact
An attacker who can control the KITTY_LISTEN_ON environment variable or influence tab title content could execute arbitrary commands in the hook's context. This runs on every tool call that updates tab state.
Fix
Replace execSync (string interpolation, spawns shell) with execFileSync (array args, no shell):
// Before (vulnerable)
execSync(`kitten @ --to="${socketPath}" set-tab-title "${escaped}"`, ...)
// After (safe)
execFileSync('kitten', ['@', `--to=${socketPath}`, 'set-tab-title', title], ...)
Also add socket path validation regex before use and replace the jq shell pipeline with native JSON parsing.
Problem
hooks/lib/tab-setter.tsusesexecSync()with string interpolation to build shell commands:This is vulnerable to command injection if
KITTY_LISTEN_ONor the tab title contains shell metacharacters. Theescapedvariable only escapes double quotes, not backticks,$(), semicolons, or other shell operators.The same pattern appears in
cleanupStaleStateFiles()which also pipes throughjq, adding another injection surface.Impact
An attacker who can control the
KITTY_LISTEN_ONenvironment variable or influence tab title content could execute arbitrary commands in the hook's context. This runs on every tool call that updates tab state.Fix
Replace
execSync(string interpolation, spawns shell) withexecFileSync(array args, no shell):Also add socket path validation regex before use and replace the
jqshell pipeline with native JSON parsing.