前端进阶之旅前端进阶之旅
基础篇
进阶篇
高频篇
精选篇
手写篇
面经篇
AI 篇
原理篇
每日一题
小程序题库
知识卡片
  • 场景篇按分类整理的大前端场景考点
  • 历年面经按年份追踪真实考点
  • 算法题库NEW在线编码即时判题
  • 专项自测100 题快速查漏
  • 前端基础
    • HTTP从报文一路讲到 HTTPS
    • 浏览器渲染、事件循环、进程
    • 计算机基础Linux、网络、操作系统
  • 进阶专项
    • 设计模式23 种模式怎么用
    • 前端系统进阶学习大型项目工程化
    • 前端综合文章长期沉淀的实践文
  • 工程与工具
    • Node学习指南从环境搭建到服务端
    • NPM工作流script、依赖与发布
    • Docker容器化部署上手
    • Canvas图形与动画实战
  • 路线与导图
    • 思维导图知识点全景图
    • 学习路线按图索骥不跑偏
  • 动态
    • 公众号动态公众号历史文章
    • 博客动态站长的技术博客
    • 开发者导航常用工具与文档站
  • AI 助手随时提问,即时解析
  • AI 模拟面试模拟真实面试 + 报告
  • AI 知识地图串起全站知识点
  • AI 定制路线按你的简历现排
AI 热点
旧版
基础篇
进阶篇
高频篇
精选篇
手写篇
面经篇
AI 篇
原理篇
每日一题
小程序题库
知识卡片
  • 场景篇按分类整理的大前端场景考点
  • 历年面经按年份追踪真实考点
  • 算法题库NEW在线编码即时判题
  • 专项自测100 题快速查漏
  • 前端基础
    • HTTP从报文一路讲到 HTTPS
    • 浏览器渲染、事件循环、进程
    • 计算机基础Linux、网络、操作系统
  • 进阶专项
    • 设计模式23 种模式怎么用
    • 前端系统进阶学习大型项目工程化
    • 前端综合文章长期沉淀的实践文
  • 工程与工具
    • Node学习指南从环境搭建到服务端
    • NPM工作流script、依赖与发布
    • Docker容器化部署上手
    • Canvas图形与动画实战
  • 路线与导图
    • 思维导图知识点全景图
    • 学习路线按图索骥不跑偏
  • 动态
    • 公众号动态公众号历史文章
    • 博客动态站长的技术博客
    • 开发者导航常用工具与文档站
  • AI 助手随时提问,即时解析
  • AI 模拟面试模拟真实面试 + 报告
  • AI 知识地图串起全站知识点
  • AI 定制路线按你的简历现排
AI 热点
旧版
返回 AI 情报前线
All News · 全部资讯9686
  • 票据遮挡测试暴露视觉模型高置信幻觉
  • 编码 Agent 的删除防护不能只匹配命令
  • Claude Code 安全加固实战指南
  • AI 测试全覆盖为何仍漏掉大量缺陷
  • MCP 成本审计改为逐轮计算工具定义
  • MCP 检查器新增易混淆工具名检测
  • RAG 文档问答如何避免越权泄露
  • 推理强度拉满,准确率未必划算
  • React Native 升级前先排查场景生命周期
  • n8n 显示成功,外部操作仍可能重复
  • Odyssey-3开放实时世界生成预览
  • 提示注入清洗中间件的设计与部署失败复盘
  • Helicon 为 Muse 编程代理提供桌面界面
  • Kotlin 健身教练用端侧视觉保护视频隐私
  • 用 AWS CLI 核算 Bedrock 单次调用费用
  • 视频生成先验输入,减少无效调用
  • OpenAmer探索不抢鼠标的桌面自动化
  • AI 开发提效要靠交付流程与质量检查
  • 如何测量语言选择对AI编码成本的影响
  • AI重命名漏掉字符串引用的隐蔽故障
  • 两万余市场实测:Jev 不敌市场价格
  • 让自主 Agent 可追踪、可恢复、可计费
  • TwinBench 用成对题检验 Agent 规则执行
  • 原子写入为何守不住模型重试次数
  • 三智能体论文审查检出七成核心论断错误
  • 给多Agent加上预算限制与人工审批
  • AgentSec 用对抗测试排查智能体安全漏洞
  • 美团如何用统一模型承接外卖多业务精排
  • Safari 空白页如何卡住 MCP 权限校验
  • 会议录音应用的说话人识别与检索踩坑
  • 给 AI 产品文档加一道事实校验关
  • 防止 Agent 靠修改测试制造假通过
  • 已加载 32 / 9686
8.0
热点
AI SCORE
技术实践2026-10-11 22:10

编码 Agent 的删除防护不能只匹配命令

dev.to · AI#Agent#命令安全#提示注入
Editor brief · 编辑速览

文章分析正常清理、空变量展开和外部指令注入三类删除场景,说明匹配字面文本 rm -rf 无法形成可靠防护。作者提出用测试展示规则失效位置,并讨论叠加防护措施。

文章思维导图
Knowledge map
拖拽缩放
Full translation

完整中文译文

如果你允许 coding Agent 执行 shell 命令,它迟早会想删除一些东西。通常这没什么问题,比如重新构建前清空 dist/。但偶尔,它会在变量为空时执行 rm -rf "$BUILD_DIR/",或者照着一份本不该信任的 README 执行清理步骤。这篇文章讨论的是:如何在真正需要拦截的场景下阻止 AI Agent 执行 rm -rf,同时让它在正常场景下依然能干活。

核心教训是:查找字面文本 rm -rf 的规则,只是一根绊线,算不上护栏。我会结合测试输出,具体展示它在哪些地方会失效,以及应该在它周围叠加哪些防护层。

为什么 Agent 会用到 rm -rf

  • 正常清理。“清理构建产物,然后再试一次”是完全合理的指令,而 rm -rf build 也是完全合理的执行方式。
  • 变量展开。rm -rf "$OUT_DIR/" 本来没问题,但如果 OUT_DIR 为空,命令就会变成 rm -rf "/"。Agent 拼接命令很快,却很少加上 set -u 防护。
  • **注入的指令。**README、issue 评论或工具返回结果里写着:“要重置环境,请运行……”。模型只是想帮忙。

禁止删除解决不了第一种情况,要求模型小心也解决不了第三种情况。你需要多层防护,而且这些防护不能依赖模型的判断。

第 1 层:缩小破坏范围

在设置任何规则之前,先限制错误删除操作能波及的范围:

  • 在容器或 VM 中,以非特权用户运行 Agent,只挂载项目目录。
  • 对于 Agent 不应修改的内容,一律以只读方式挂载。只读 bind mount 不在乎命令是怎么写的。
  • 把工作交给 Agent 前,先 commit 或 stash。只要 git status 干净,工作区里的大多数删除操作都能通过 git checkout . 恢复。
  • 对于 Agent 能接触到、但不在 git 管理范围内的内容,保留备份。

只有这一层完全不受命令语法影响。后面的每一层,都是为了更早识别操作意图。

第 2 层:Agent 级别的拒绝规则

大多数 coding Agent 都允许你按命令模式设置拒绝规则。例如,在 Claude Code 中:

{
  "permissions": {
    "deny": ["Bash(rm -rf *)", "Bash(rm -fr *)"]
  }
}

Gemini CLI 等工具也有类似机制。应该用起来,但也要清楚它们的局限。旧版 Gemini CLI 文档说得很直白:基于简单字符串匹配、针对特定命令的限制“很容易被绕过”。任何前缀或子串匹配规则都存在同样的问题。

用测试证明:字面匹配规则遇上真实命令写法

下面这份策略使用 Cirvix policy DSL 编写,包含一条针对字面字符串的拒绝规则,以及一条宽松的 shell 放行规则。其中,command = "rm -rf" 会被编译为 contains 匹配:

deny:
  name = deny-destructive-shell
  tool = shell.exec
  command = "rm -rf"

allow:
  name = allow-shell
  tool = shell.exec

test "rm -rf":
  tool = shell.exec
  command = rm -rf ./build
  expect deny
test "rm -fr":
  tool = shell.exec
  command = rm -fr ./build
  expect deny
test "rm -r -f":
  tool = shell.exec
  command = rm -r -f ./build
  expect deny
test "find delete":
  tool = shell.exec
  command = find . -delete
  expect deny

对这份策略运行 cirvix policy test,使用的软件包版本为 0.3.0:

  ✓ rm -rf  → deny (deny-destructive-shell)
  ✗ rm -fr  line 15
      expected  deny
      actual    allow  by allow-shell
      call      shell.exec   risk CRITICAL
  ✗ rm -r -f  line 19
      expected  deny
      actual    allow  by allow-shell
      call      shell.exec   risk CRITICAL
  ✗ find delete  line 23
      expected  deny
      actual    allow  by allow-shell
      call      shell.exec   risk HIGH

  3 failed  1 passed

拦住了一种写法,漏掉了三种。不过,请留意 risk 列:引擎已经将 rm -fr 和 rm -r -f 归类为 CRITICAL,将 find -delete 归类为 HIGH。只是这条字面匹配规则根本没有查询风险等级。

第 3 层:先对命令分类,再按类别决策

解决办法是根据命令实际执行什么操作来编写规则,而不是根据它怎么写;同时,绝不能让通配放行规则覆盖危险类别:

deny:
  name = deny-rm-rf-literal
  tool = shell.exec
  command = "rm -rf"

deny:
  name = deny-critical-shell
  tool = shell.exec
  risk >= CRITICAL
  reason = "A CRITICAL command must be permitted by a rule that names it, never by a wildcard."

require_approval:
  name = hold-high-risk-shell
  tool = shell.exec
  risk >= HIGH
  approvers = developer

allow:
  name = allow-safe-shell
  tool = shell.exec
  risk <= MEDIUM

使用同类测试用例,再加上几个更贴近实际的场景:

  ✓ rm -rf  → deny (deny-rm-rf-literal)
  ✓ rm -fr  → deny (deny-critical-shell)
  ✓ rm -r -f  → deny (deny-critical-shell)
  ✓ rm with empty variable  → deny (deny-rm-rf-literal)
  ✓ find -delete  → require_approval (hold-high-risk-shell)
  ✓ python rmtree  → require_approval (hold-high-risk-shell)
  ✓ git clean  → require_approval (hold-high-risk-shell)
  ✓ npm test  → allow (allow-safe-shell)

  8/8 PASSED
  • 无论参数顺序如何,递归强制删除都会按类别被拒绝,不再依赖文本匹配。
  • 对于分类器无法认定为安全的命令,例如 find -delete、python -c "shutil.rmtree(...)"、git clean -fdx,都会暂停执行,交由人工审批,而不是悄悄放行。对于“我无法判断具体行为的任意执行”,这才是正确的默认处理方式。
  • 日常命令仍然可以执行。npm test 位于一份简短、带锚定匹配的允许列表中,不会被打断。

分类器刻意采用规则,而不是模型:同一条命令每次都会得到相同的风险等级。只要命令包含串联或替换字符,如 ;、&&、|、$(),就会失去进入安全允许列表的资格,因此 npm test; rm -rf ~ 无法借着 npm test 混进来。

第 4 层:像测试代码一样测试策略

无论使用什么引擎,都应该维护一份危险命令写法的列表,并在 CI 中运行测试。可以从下面这些开始:

rm -rf ./build          rm -fr ./build         rm -r -f dist
rm -rf "$EMPTY/"        find . -delete         git clean -fdx
python3 -c "import shutil; shutil.rmtree('x')"
xargs rm -rf < list.txt  npm test; rm -rf ~

如果某条新规则错误地放行了其中一条命令,你会在 pull request 阶段发现,而不是等到事故发生后才知道。

这些防护覆盖不到什么

策略只能看到经过它的调用。如果 Agent 能通过其他方式启动 shell,或者运行一份你从未检查过内容的脚本,策略评估的只是外层命令,例如 ./scripts/clean.sh。按照上面的规则,这条命令会因无法识别而被暂缓执行。这是一个合理的默认处理方式,但并不意味着策略能看到脚本内部。第 1 层防护仍然必须保留。

用 Cirvix 试一试

Cirvix AgentControl 是一个开源策略引擎,用于治理 AI Agent 的工具调用:它可以通过 Claude Code hook 管理 shell 命令,通过 gateway 管理 MCP 调用,也可以管理使用其 Node/Python SDK 封装的函数。上面的策略可以通过以下命令验证并运行:

npm install -g @cirvix_ai/agent-control
cirvix policy check --policy shell.policy
cirvix policy test  --policy shell.policy

仓库中的 policies/default.policy 提供了一份更完整的基线策略,覆盖破坏性 shell 操作、历史记录重写、软件包安装和生产部署,并附有对应的测试用例。Cirvix 无法阻止 prompt injection,也只能治理经过它的调用;它提供的是命令执行前经过测试、可解释的决策。

仓库:CIRVIX/agent-control。文档与指南:Cirvix 官网。

如果需要采取进一步措施,可以考虑屏蔽此人和/或举报滥用行为。

Original source

本文由 AI 翻译整理自 dev.to · AI,原文版权归原作者所有。

阅读英文原文
上一篇
票据遮挡测试暴露视觉模型高置信幻觉
下一篇
Claude Code 安全加固实战指南