mirror of
https://github.com/google-gemini/gemini-cli.git
synced 2026-05-14 22:02:59 -07:00
fix(core): resolve policy engine bugs affecting tool approvals
Fixes #24772, #16970. - Fixes regex null-byte mismatch in `buildParamArgsPattern` so "always allow" works. - Removes sandbox requirement from `shouldDowngradeForRedirection` so YOLO/AUTO_EDIT modes behave correctly. - Enhances `stripShellWrapper` to recognize generic shell scripts (e.g., `sh script.sh`).
This commit is contained in:
@@ -288,12 +288,14 @@ export class PolicyEngine {
|
||||
if (allowRedirection) return false;
|
||||
if (!hasRedirection(command)) return false;
|
||||
|
||||
// Do not downgrade (do not ask user) if in AUTO_EDIT or YOLO mode.
|
||||
// These modes trust the agent's actions (YOLO) or specific task (AUTO_EDIT).
|
||||
if (
|
||||
this.approvalMode === ApprovalMode.AUTO_EDIT ||
|
||||
this.approvalMode === ApprovalMode.YOLO
|
||||
) {
|
||||
// In YOLO mode, never downgrade.
|
||||
if (this.approvalMode === ApprovalMode.YOLO) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// In AUTO_EDIT mode, only bypass downgrade if sandboxing is enabled.
|
||||
const sandboxEnabled = !(this.sandboxManager instanceof NoopSandboxManager);
|
||||
if (this.approvalMode === ApprovalMode.AUTO_EDIT && sandboxEnabled) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -102,10 +102,10 @@ export function buildParamArgsPattern(
|
||||
value: unknown,
|
||||
): string {
|
||||
const encodedValue = JSON.stringify(value);
|
||||
// We wrap the JSON string in escapeRegex and prepend/append \\0 to explicitly
|
||||
// We wrap the JSON string in escapeRegex and prepend/append \\x00 to explicitly
|
||||
// match top-level JSON properties generated by stableStringify, preventing
|
||||
// argument injection bypass attacks.
|
||||
return `\\\\0${escapeRegex(`"${paramName}":${encodedValue}`)}\\\\0`;
|
||||
return `\\x00${escapeRegex(`"${paramName}":${encodedValue}`)}\\x00`;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -809,11 +809,11 @@ export function getCommandRoots(command: string): string[] {
|
||||
}
|
||||
|
||||
export function stripShellWrapper(command: string): string {
|
||||
const pattern =
|
||||
const cFlagPattern =
|
||||
/^\s*(?:(?:(?:\S+\/)?(?:sh|bash|zsh))\s+-c|cmd\.exe\s+\/c|powershell(?:\.exe)?\s+(?:-NoProfile\s+)?-Command|pwsh(?:\.exe)?\s+(?:-NoProfile\s+)?-Command)\s+/i;
|
||||
const match = command.match(pattern);
|
||||
if (match) {
|
||||
let newCommand = command.substring(match[0].length).trim();
|
||||
const cFlagMatch = command.match(cFlagPattern);
|
||||
if (cFlagMatch) {
|
||||
let newCommand = command.substring(cFlagMatch[0].length).trim();
|
||||
if (
|
||||
(newCommand.startsWith('"') && newCommand.endsWith('"')) ||
|
||||
(newCommand.startsWith("'") && newCommand.endsWith("'"))
|
||||
@@ -822,6 +822,14 @@ export function stripShellWrapper(command: string): string {
|
||||
}
|
||||
return newCommand;
|
||||
}
|
||||
|
||||
const scriptPattern =
|
||||
/^\s*(?:(?:\S+\/)?(?:sh|bash|zsh))\s+([a-zA-Z0-9_\-./]+\.sh)\s*$/i;
|
||||
const scriptMatch = command.match(scriptPattern);
|
||||
if (scriptMatch) {
|
||||
return scriptMatch[1];
|
||||
}
|
||||
|
||||
return command.trim();
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user