fix: run dangerous path check before auto-allowing rm/rmdir in acceptEdits mode (#246)
In acceptEdits mode, filesystem commands (rm, rmdir, mv, cp, sed, mkdir, touch) were returned as 'allow' before checkDangerousRemovalPaths ran. This meant rm -rf ~ and rm -rf / bypassed the dangerous path guard entirely. Fix: - Export checkDangerousRemovalPaths from pathValidation.ts - In modeValidation.ts, call it for rm/rmdir before returning allow - Safe paths (rm file.txt) continue to auto-allow unchanged - Dangerous paths (rm -rf ~) now return 'ask' requiring user approval This is a defense-in-depth guard that matters most for 3P models (local Ollama, DeepSeek etc.) that lack built-in refusal training and would blindly execute destructive commands in acceptEdits mode. Fixes finding 3 from issue #244. Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -1,8 +1,10 @@
|
||||
import type { z } from 'zod/v4'
|
||||
import type { ToolPermissionContext } from '../../Tool.js'
|
||||
import { splitCommand_DEPRECATED } from '../../utils/bash/commands.js'
|
||||
import { getCwd } from '../../utils/cwd.js'
|
||||
import type { PermissionResult } from '../../utils/permissions/PermissionResult.js'
|
||||
import type { BashTool } from './BashTool.js'
|
||||
import { checkDangerousRemovalPaths } from './pathValidation.js'
|
||||
|
||||
const ACCEPT_EDITS_ALLOWED_COMMANDS = [
|
||||
'mkdir',
|
||||
@@ -39,6 +41,17 @@ function validateCommandForMode(
|
||||
toolPermissionContext.mode === 'acceptEdits' &&
|
||||
isFilesystemCommand(baseCmd)
|
||||
) {
|
||||
// Guard: always run dangerous path check for rm/rmdir before auto-allowing.
|
||||
// This prevents rm -rf ~ / rm -rf / from bypassing checkDangerousRemovalPaths
|
||||
// which is otherwise skipped when acceptEdits returns allow early.
|
||||
if (baseCmd === 'rm' || baseCmd === 'rmdir') {
|
||||
const args = trimmedCmd.split(/\s+/).slice(1)
|
||||
const dangerousResult = checkDangerousRemovalPaths(baseCmd, args, getCwd())
|
||||
if (dangerousResult.behavior !== 'passthrough') {
|
||||
return dangerousResult
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
behavior: 'allow',
|
||||
updatedInput: { command: cmd },
|
||||
|
||||
@@ -67,7 +67,7 @@ export type PathCommand =
|
||||
* require explicit user approval, even if allowlist rules exist.
|
||||
* This prevents catastrophic data loss from commands like `rm -rf /`.
|
||||
*/
|
||||
function checkDangerousRemovalPaths(
|
||||
export function checkDangerousRemovalPaths(
|
||||
command: 'rm' | 'rmdir',
|
||||
args: string[],
|
||||
cwd: string,
|
||||
|
||||
Reference in New Issue
Block a user