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:
KRATOS
2026-04-04 19:32:02 +05:30
committed by GitHub
parent 4c3118e071
commit 0951c8bc59
2 changed files with 14 additions and 1 deletions

View File

@@ -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 },

View File

@@ -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,