feat(security): 危险工具审批门与 Bash 工作区沙箱策略#175
Open
Bsyy95 wants to merge 1 commit into
Open
Conversation
Dangerous tool calls executed the moment the model asked for them: recursive Delete, mutating SSHManager actions, and Bash/ManagedProcess with a cwd outside the workspace all ran with no user consent, while the Gateway lets remote sessions and cron/subagent runs drive the same tools unattended. The file-tool sandbox was also trivially bypassable because Bash cwd always resolved with allowExternal. This adds two opt-in safety layers (defaults preserve current behavior): Tool approval gate (system.toolApprovalMode = "dangerous"): a pure policy module classifies dangerous calls - Delete, mutating SSHManager actions, and shell calls whose cwd conservatively resolves outside the workspace (absolute paths, ~, file://, ".." escapes). The agent runner gates them in beforeToolCall: with an approval callback the run pauses on a desktop confirmation modal (FIFO queue for parallel calls, abort signal settles pending requests as denied); without a callback - remote gateway sessions and delegated subagent runs - the call is denied with an explanatory tool error. Deny/unattended texts teach the model to adjust course instead of retrying. Bash cwd policy (system.bashCwdPolicy = "workspace-only"): Bash and ManagedProcess cwd resolution drops allowExternal so out-of-workspace working directories fail at resolve time with a hint that the restriction comes from settings. Settings UI gains a security card (approval toggle + cwd scope picker) with zh/en strings; the WebUI settings normalizer mirrors the new fields so browser-side saves keep them intact. Co-authored-by: Cursor <cursoragent@cursor.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
摘要
LiveAgent 的定位是"可远程遥控的本地全能代理"(Gateway 远程会话、cron 定时任务、子代理常驻运行),但目前任何危险工具调用都在模型发起的瞬间直接执行:递归 Delete、SSHManager 的变更操作、以及
cwd指向工作区外的 Bash / ManagedProcess——全程没有任何用户确认环节。同时文件工具的工作区沙箱对 Bash 形同虚设:cwd恒以allowExternal: true解析,命令可以在整台机器的任意目录运行。MCP 第三方工具、ClawHub 安装的 Skills、网页搜索结果都是提示注入的入口;"人不在电脑前、代理自己在跑"恰恰是本项目的核心场景。本 PR 增加两层默认关闭(不改变存量行为)的安全能力,对标 Claude Code 的 permission prompt 与 Codex CLI 的 approval modes,并针对远程/委托场景做了更严格的处理。
改动内容
1. 危险操作审批门(
system.toolApprovalMode = "dangerous")lib/chat/runner/toolApprovalPolicy.ts,判定三类危险调用:exec/send_input/sftp_delete/sftp_rename/sftp_upload/sftp_download/sftp_write_text/sftp_mkdir)——只读查询不打扰;~、file://、含..段的相对路径;skill://除外),宁可多问一次也不漏逃逸。beforeToolCall处设门(复用 pi-agent-core 的异步 hook 与{block, reason}契约):sshManagerRemoteAllowed用gatewayBridgeRequest判定远程来源的既有先例。2. Bash 工作目录范围(
system.bashCwdPolicy = "workspace-only")createShellTools新增externalCwdAllowed;锁定时 Bash / ManagedProcess 的cwd解析不再放行外部路径,在解析期即失败,报错追加一句提示说明限制来自设置(避免模型误以为路径拼写错误)。审批门是"问一下",这层是硬边界,两者可独立启用。3. 设置与 UI
SystemSettings新增toolApprovalMode(off|dangerous,默认off)与bashCwdPolicy(unrestricted|workspace-only,默认unrestricted);normalize 齐全。ToolApprovalModal(危险类型说明 + 参数摘要 + 允许/拒绝),zh/en 文案齐全。默认行为
两项均默认关闭,存量用户零感知;建议在 README/文档中引导远程部署用户开启。后续可以讨论把远程会话的默认值收紧一档。
测试
tool-approval-policy.test.mjs(7 组):策略关闭零打扰、Delete/SSH action 分级、外部 cwd 判定矩阵(分隔符/大小写/~/file:///..逃逸/skill:// 豁免)、拒绝文案、摘要截断。shell-tools.test.mjs新增 2 组:workspace-only 下外部 cwd 在解析期拒绝且不触发 shell 调用(含设置来源提示断言)、默认行为不变。normalization.test.mjs新增设置归一化用例(默认值 / 合法值 / 非法值回退)。pnpm test:frontend1053 个测试全部通过;GUI 与 WebUI 的build/lint通过;WebUI 368 个测试通过;check-mirror(87 文件)、git diff --check干净。