Added warning to avoid command substitution in run_shell_command tool… (#9934)

Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
This commit is contained in:
owenofbrien
2025-09-26 13:16:05 -05:00
committed by GitHub
parent 3d7cb3fb8a
commit e909993dd1
3 changed files with 25 additions and 3 deletions
+10 -2
View File
@@ -395,10 +395,18 @@ function getShellToolDescription(): string {
} }
function getCommandDescription(): string { function getCommandDescription(): string {
const cmd_substitution_warning =
'\n*** WARNING: Command substitution using $(), `` ` ``, <(), or >() is not allowed for security reasons.';
if (os.platform() === 'win32') { if (os.platform() === 'win32') {
return 'Exact command to execute as `cmd.exe /c <command>`'; return (
'Exact command to execute as `cmd.exe /c <command>`' +
cmd_substitution_warning
);
} else { } else {
return 'Exact bash command to execute as `bash -c <command>`'; return (
'Exact bash command to execute as `bash -c <command>`' +
cmd_substitution_warning
);
} }
} }
@@ -145,6 +145,15 @@ describe('isCommandAllowed', () => {
expect(result.reason).toContain('Command substitution'); expect(result.reason).toContain('Command substitution');
}); });
it('should block command substitution using `>(...)`', () => {
const result = isCommandAllowed(
'echo "Log message" > >(tee log.txt)',
config,
);
expect(result.allowed).toBe(false);
expect(result.reason).toContain('Command substitution');
});
it('should block command substitution using backticks', () => { it('should block command substitution using backticks', () => {
const result = isCommandAllowed('echo `rm -rf /`', config); const result = isCommandAllowed('echo `rm -rf /`', config);
expect(result.allowed).toBe(false); expect(result.allowed).toBe(false);
+6 -1
View File
@@ -266,6 +266,11 @@ export function detectCommandSubstitution(command: string): boolean {
return true; return true;
} }
// >(...) process substitution - works unquoted only (not in double quotes)
if (char === '>' && nextChar === '(' && !inDoubleQuotes && !inBackticks) {
return true;
}
// Backtick command substitution - check for opening backtick // Backtick command substitution - check for opening backtick
// (We track the state above, so this catches the start of backtick substitution) // (We track the state above, so this catches the start of backtick substitution)
if (char === '`' && !inBackticks) { if (char === '`' && !inBackticks) {
@@ -319,7 +324,7 @@ export function checkCommandPermissions(
allAllowed: false, allAllowed: false,
disallowedCommands: [command], disallowedCommands: [command],
blockReason: blockReason:
'Command substitution using $(), <(), or >() is not allowed for security reasons', 'Command substitution using $(), `` ` ``, <(), or >() is not allowed for security reasons',
isHardDenial: true, isHardDenial: true,
}; };
} }