mirror of
https://github.com/RooVetGit/Roo-Code.git
synced 2026-09-07 08:26:51 +00:00
fix: ensure commands require explicit approval when auto-approval is disabled
- Fixed issue where commands were being auto-executed without user consent - Added check to ensure BOTH autoApprovalEnabled AND alwaysAllowExecute must be true - Added comprehensive tests to verify the fix - Fixes #9606
This commit is contained in:
parent
3806b3d27d
commit
5b3b8c7384
2 changed files with 171 additions and 1 deletions
165
src/core/auto-approval/__tests__/checkAutoApproval.spec.ts
Normal file
165
src/core/auto-approval/__tests__/checkAutoApproval.spec.ts
Normal file
|
|
@ -0,0 +1,165 @@
|
|||
import { describe, it, expect } from "vitest"
|
||||
import { checkAutoApproval } from "../index"
|
||||
|
||||
describe("checkAutoApproval", () => {
|
||||
describe("command auto-approval", () => {
|
||||
it("should ask user when autoApprovalEnabled is false, even if alwaysAllowExecute is true", async () => {
|
||||
const state = {
|
||||
autoApprovalEnabled: false,
|
||||
alwaysAllowExecute: true,
|
||||
allowedCommands: ["*"],
|
||||
deniedCommands: [],
|
||||
}
|
||||
|
||||
const result = await checkAutoApproval({
|
||||
state,
|
||||
ask: "command",
|
||||
text: "echo hello",
|
||||
})
|
||||
|
||||
expect(result.decision).toBe("ask")
|
||||
})
|
||||
|
||||
it("should ask user when alwaysAllowExecute is false, even if autoApprovalEnabled is true", async () => {
|
||||
const state = {
|
||||
autoApprovalEnabled: true,
|
||||
alwaysAllowExecute: false,
|
||||
allowedCommands: ["*"],
|
||||
deniedCommands: [],
|
||||
}
|
||||
|
||||
const result = await checkAutoApproval({
|
||||
state,
|
||||
ask: "command",
|
||||
text: "echo hello",
|
||||
})
|
||||
|
||||
expect(result.decision).toBe("ask")
|
||||
})
|
||||
|
||||
it("should auto-approve when both autoApprovalEnabled and alwaysAllowExecute are true and command is allowed", async () => {
|
||||
const state = {
|
||||
autoApprovalEnabled: true,
|
||||
alwaysAllowExecute: true,
|
||||
allowedCommands: ["echo"],
|
||||
deniedCommands: [],
|
||||
}
|
||||
|
||||
const result = await checkAutoApproval({
|
||||
state,
|
||||
ask: "command",
|
||||
text: "echo hello",
|
||||
})
|
||||
|
||||
expect(result.decision).toBe("approve")
|
||||
})
|
||||
|
||||
it("should auto-deny when both autoApprovalEnabled and alwaysAllowExecute are true but command is denied", async () => {
|
||||
const state = {
|
||||
autoApprovalEnabled: true,
|
||||
alwaysAllowExecute: true,
|
||||
allowedCommands: ["*"],
|
||||
deniedCommands: ["rm"],
|
||||
}
|
||||
|
||||
const result = await checkAutoApproval({
|
||||
state,
|
||||
ask: "command",
|
||||
text: "rm -rf /",
|
||||
})
|
||||
|
||||
expect(result.decision).toBe("deny")
|
||||
})
|
||||
|
||||
it("should ask user when both autoApprovalEnabled and alwaysAllowExecute are true but command is not in allowlist", async () => {
|
||||
const state = {
|
||||
autoApprovalEnabled: true,
|
||||
alwaysAllowExecute: true,
|
||||
allowedCommands: ["echo", "ls"],
|
||||
deniedCommands: [],
|
||||
}
|
||||
|
||||
const result = await checkAutoApproval({
|
||||
state,
|
||||
ask: "command",
|
||||
text: "cat /etc/passwd",
|
||||
})
|
||||
|
||||
expect(result.decision).toBe("ask")
|
||||
})
|
||||
|
||||
it("should ask user when no text is provided", async () => {
|
||||
const state = {
|
||||
autoApprovalEnabled: true,
|
||||
alwaysAllowExecute: true,
|
||||
allowedCommands: ["*"],
|
||||
deniedCommands: [],
|
||||
}
|
||||
|
||||
const result = await checkAutoApproval({
|
||||
state,
|
||||
ask: "command",
|
||||
text: undefined,
|
||||
})
|
||||
|
||||
expect(result.decision).toBe("ask")
|
||||
})
|
||||
|
||||
it("should ask user when both flags are undefined", async () => {
|
||||
const state = {
|
||||
allowedCommands: ["*"],
|
||||
deniedCommands: [],
|
||||
}
|
||||
|
||||
const result = await checkAutoApproval({
|
||||
state,
|
||||
ask: "command",
|
||||
text: "echo hello",
|
||||
})
|
||||
|
||||
expect(result.decision).toBe("ask")
|
||||
})
|
||||
|
||||
it("should ask user when state is undefined", async () => {
|
||||
const result = await checkAutoApproval({
|
||||
state: undefined,
|
||||
ask: "command",
|
||||
text: "echo hello",
|
||||
})
|
||||
|
||||
expect(result.decision).toBe("ask")
|
||||
})
|
||||
})
|
||||
|
||||
describe("other ask types", () => {
|
||||
it("should handle non-command asks normally when autoApprovalEnabled is true", async () => {
|
||||
const state = {
|
||||
autoApprovalEnabled: true,
|
||||
alwaysAllowReadOnly: true,
|
||||
}
|
||||
|
||||
const result = await checkAutoApproval({
|
||||
state,
|
||||
ask: "tool",
|
||||
text: JSON.stringify({ tool: "readFile", path: "test.txt" }),
|
||||
})
|
||||
|
||||
expect(result.decision).toBe("approve")
|
||||
})
|
||||
|
||||
it("should ask for non-command asks when autoApprovalEnabled is false", async () => {
|
||||
const state = {
|
||||
autoApprovalEnabled: false,
|
||||
alwaysAllowReadOnly: true,
|
||||
}
|
||||
|
||||
const result = await checkAutoApproval({
|
||||
state,
|
||||
ask: "tool",
|
||||
text: JSON.stringify({ tool: "readFile", path: "test.txt" }),
|
||||
})
|
||||
|
||||
expect(result.decision).toBe("ask")
|
||||
})
|
||||
})
|
||||
})
|
||||
|
|
@ -117,7 +117,9 @@ export async function checkAutoApproval({
|
|||
return { decision: "ask" }
|
||||
}
|
||||
|
||||
if (state.alwaysAllowExecute === true) {
|
||||
// Only auto-approve commands if both autoApprovalEnabled AND alwaysAllowExecute are true
|
||||
// This prevents commands from being executed without user consent when auto-approval is disabled
|
||||
if (state.autoApprovalEnabled === true && state.alwaysAllowExecute === true) {
|
||||
const decision = getCommandDecision(text, state.allowedCommands || [], state.deniedCommands || [])
|
||||
|
||||
if (decision === "auto_approve") {
|
||||
|
|
@ -128,6 +130,9 @@ export async function checkAutoApproval({
|
|||
return { decision: "ask" }
|
||||
}
|
||||
}
|
||||
|
||||
// If auto-approval is disabled or alwaysAllowExecute is false, always ask the user
|
||||
return { decision: "ask" }
|
||||
}
|
||||
|
||||
if (ask === "tool") {
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue