Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 33 additions & 0 deletions packages/core/src/policy/policy-engine.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1762,6 +1762,39 @@ describe('PolicyEngine', () => {
});

describe('shell command parsing failure', () => {
it('should return ALLOW in YOLO mode for dangerous commands due to heuristics override', async () => {
// Create an engine with YOLO mode and a sandbox manager that flags a command as dangerous
const rules: PolicyRule[] = [
{
toolName: '*',
decision: PolicyDecision.ALLOW,
priority: 999,
modes: [ApprovalMode.YOLO],
},
];

const mockSandboxManager = new NoopSandboxManager();
mockSandboxManager.isDangerousCommand = vi.fn().mockReturnValue(true);
mockSandboxManager.isKnownSafeCommand = vi.fn().mockReturnValue(false);

engine = new PolicyEngine({
rules,
approvalMode: ApprovalMode.YOLO,
sandboxManager: mockSandboxManager,
});

const result = await engine.check(
{
name: 'run_shell_command',
args: { command: 'powershell echo "dangerous"' },
},
undefined,
);

// Even though the command is flagged as dangerous, YOLO mode should preserve the ALLOW decision
expect(result.decision).toBe(PolicyDecision.ALLOW);
});

it('should return ALLOW in YOLO mode even if shell command parsing fails', async () => {
const { splitCommands } = await import('../utils/shell-utils.js');
const rules: PolicyRule[] = [
Expand Down
7 changes: 7 additions & 0 deletions packages/core/src/policy/policy-engine.ts
Original file line number Diff line number Diff line change
Expand Up @@ -312,6 +312,13 @@ export class PolicyEngine {
const parsedArgs = parsedObjArgs.map(extractStringFromParseEntry);

if (this.sandboxManager.isDangerousCommand(parsedArgs)) {
if (this.approvalMode === ApprovalMode.YOLO) {
debugLogger.debug(
`[PolicyEngine.check] Command evaluated as dangerous, but YOLO mode is active. Preserving decision: ${command}`,
);
return decision;
}
Comment thread
galz10 marked this conversation as resolved.

debugLogger.debug(
`[PolicyEngine.check] Command evaluated as dangerous, forcing ASK_USER: ${command}`,
);
Expand Down
5 changes: 5 additions & 0 deletions packages/core/src/tools/shell.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ import {
} from '../utils/shell-utils.js';
import { SHELL_TOOL_NAME } from './tool-names.js';
import { PARAM_ADDITIONAL_PERMISSIONS } from './definitions/base-declarations.js';
import { ApprovalMode } from '../policy/types.js';
import type { MessageBus } from '../confirmation-bus/message-bus.js';
import { getShellDefinition } from './definitions/coreTools.js';
import { resolveToolDeclaration } from './definitions/resolver.js';
Expand Down Expand Up @@ -252,6 +253,10 @@ export class ShellToolInvocation extends BaseToolInvocation<
abortSignal: AbortSignal,
forcedDecision?: ForcedToolDecision,
): Promise<ToolCallConfirmationDetails | false> {
if (this.context.config.getApprovalMode() === ApprovalMode.YOLO) {
return super.shouldConfirmExecute(abortSignal, forcedDecision);
}

if (this.params[PARAM_ADDITIONAL_PERMISSIONS]) {
return this.getConfirmationDetails(abortSignal);
}
Expand Down
Loading