mirror of
https://github.com/google-gemini/gemini-cli.git
synced 2026-04-25 04:24:51 -07:00
@@ -480,6 +480,18 @@ describe('ShellTool', () => {
|
||||
invocation.shouldConfirmExecute(new AbortController().signal),
|
||||
).rejects.toThrow('wc');
|
||||
});
|
||||
|
||||
it('should require all segments of a chained command to be allowlisted', async () => {
|
||||
(mockConfig.getAllowedTools as Mock).mockReturnValue([
|
||||
'ShellTool(echo)',
|
||||
]);
|
||||
const invocation = shellTool.build({ command: 'echo "foo" && ls -l' });
|
||||
await expect(
|
||||
invocation.shouldConfirmExecute(new AbortController().signal),
|
||||
).rejects.toThrow(
|
||||
'Command "echo "foo" && ls -l" is not in the list of allowed tools for non-interactive mode.',
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -9,6 +9,7 @@ import path from 'node:path';
|
||||
import os, { EOL } from 'node:os';
|
||||
import crypto from 'node:crypto';
|
||||
import type { Config } from '../config/config.js';
|
||||
import type { AnyToolInvocation } from '../index.js';
|
||||
import { ToolErrorType } from './tool-error.js';
|
||||
import type {
|
||||
ToolInvocation,
|
||||
@@ -36,10 +37,9 @@ import {
|
||||
getCommandRoots,
|
||||
initializeShellParsers,
|
||||
isCommandAllowed,
|
||||
SHELL_TOOL_NAMES,
|
||||
isShellInvocationAllowlisted,
|
||||
stripShellWrapper,
|
||||
} from '../utils/shell-utils.js';
|
||||
import { doesToolInvocationMatch } from '../utils/tool-utils.js';
|
||||
import { SHELL_TOOL_NAME } from './tool-names.js';
|
||||
|
||||
export const OUTPUT_UPDATE_INTERVAL_MS = 1000;
|
||||
@@ -90,9 +90,7 @@ export class ShellToolInvocation extends BaseToolInvocation<
|
||||
!this.config.isInteractive() &&
|
||||
this.config.getApprovalMode() !== ApprovalMode.YOLO
|
||||
) {
|
||||
const allowedTools = this.config.getAllowedTools() || [];
|
||||
const [SHELL_TOOL_NAME] = SHELL_TOOL_NAMES;
|
||||
if (doesToolInvocationMatch(SHELL_TOOL_NAME, command, allowedTools)) {
|
||||
if (this.isInvocationAllowlisted(command)) {
|
||||
// If it's an allowed shell command, we don't need to confirm execution.
|
||||
return false;
|
||||
}
|
||||
@@ -324,6 +322,16 @@ export class ShellToolInvocation extends BaseToolInvocation<
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private isInvocationAllowlisted(command: string): boolean {
|
||||
const allowedTools = this.config.getAllowedTools() || [];
|
||||
if (allowedTools.length === 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const invocation = { params: { command } } as unknown as AnyToolInvocation;
|
||||
return isShellInvocationAllowlisted(invocation, allowedTools);
|
||||
}
|
||||
}
|
||||
|
||||
function getShellToolDescription(): string {
|
||||
|
||||
Reference in New Issue
Block a user