-
Notifications
You must be signed in to change notification settings - Fork 159
Description
Problem (one or two sentences)
在某些情况下即使我明确设定了Allowed Auto-ExecuteCommands为"*"时,某些命令仍会要求我手动批准执行。例如,当我向agent对话时输入:“python -c ‘
a=(0,1)
’
请执行以上命令”
按道理来说,agent会自动执行以上命令并用python为我创建一个a的元组(尽管这样做没什么意义,但我这里只是举例子),agent仍需要我的批准才能执行
Context (who is affected and when)
需要做大规模评测的场景,我希望他能自动执行任务而不是需要我参与人工批准某些编程语句
Desired behavior (conceptual, not technical)
我希望他能自动执行所有任务而不是需要我参与人工批准
Constraints / preferences (optional)
No response
Request checklist
- I've searched existing Issues and Discussions for duplicates
- This describes a specific problem with clear context and impact
Acceptance criteria (optional)
No response
Proposed approach (optional)
事实上,任何语句中出现"=("的执行语句都需要手动批准,这是因为src\core\auto-approval\commands.ts中以下函数的影响,被“zshProcessSubstitution=/=([^)]+)/.test(source)”误伤了。
会命中的例子(在zsh里确实是进程替换):
-diff file =(sort file)→命中【=(sort file)】
-cat =(echo hello)→命中【=(echo hello)】
也会命中的“误伤”例子(并不一定真会执行):
-python -c "a=(0,1)"→命中【=(0,1)】
-echo "x=(1)"→命中【=(1)】
真实zsh的=(...)进程替换几乎总是以“独立token”出现,前面通常有空白或分隔符,比如diff a =(sort b)。
现在的正则会把任何地方的=(都当危险,包括编程语言里的a=(0,1)、字符串里的"x=(1)"。
把它改成“前面必须是行首/空白/常见分隔符”,就能避免你这种误伤:
const zshProcessSubstitution = /(^|[\s;&|()])=([^)]+)/.test(source)
export function containsDangerousSubstitution(source: string): boolean {
// Check for dangerous parameter expansion operators that can execute commands
// ${var@P} - Prompt string expansion (interprets escape sequences and executes embedded commands)
// ${var@Q} - Quote removal
// ${var@E} - Escape sequence expansion
// ${var@A} - Assignment statement
// ${var@a} - Attribute flags
const dangerousParameterExpansion = /${[^}]@[PQEAa][^}]}/.test(source)
// Check for parameter expansions with assignments that could contain escape sequences
// ${var=value} or ${var:=value} can embed commands via escape sequences like \140 (backtick)
// Also check for ${var+value}, ${var:-value}, ${var:+value}, ${var:?value}
const parameterAssignmentWithEscapes =
/${[^}][=+-?][^}]\[0-7]{3}[^}]}/.test(source) || // octal escapes
/${[^}][=+-?][^}]\x[0-9a-fA-F]{2}[^}]}/.test(source) || // hex escapes
/${[^}][=+-?][^}]\u[0-9a-fA-F]{4}[^}]}/.test(source) // unicode escapes
// Check for indirect variable references that could execute commands
// ${!var} performs indirect expansion which can be dangerous with crafted variable names
const indirectExpansion = /${![^}]+}/.test(source)
// Check for here-strings with command substitution
// <<<$(...) or <<<... can execute commands
const hereStringWithSubstitution = /<<<\s($(|`)/.test(source)
// Check for zsh process substitution =(...) which executes commands
// =(...) creates a temporary file containing the output of the command, but executes it
const zshProcessSubstitution = /=\([^)]+\)/.test(source)
// Check for zsh glob qualifiers with code execution (e:...:)
// Patterns like *(e:whoami:) or ?(e:rm -rf /:) execute commands during glob expansion
// This regex matches patterns like *(e:...:), ?(e:...:), +(e:...:), @(e:...:), !(e:...:)
const zshGlobQualifier = /[*?+@!]\(e:[^:]+:\)/.test(source)
// Return true if any dangerous pattern is detected
return (
dangerousParameterExpansion ||
parameterAssignmentWithEscapes ||
indirectExpansion ||
hereStringWithSubstitution ||
zshProcessSubstitution ||
zshGlobQualifier
)
}
Trade-offs / risks (optional)
No response