核心摘要:恶意 AGENTS.md 之所以能劫持编程 Agent,利用的正是这类文件的设计机制:启动时自动读取并照章执行。2026 年 10 月,Forever Security 在一台客户电脑的 ~/Downloads 目录捕获了这起攻击。五步防护可以堵住它:不在不受控目录启动 Agent、像审阅代码一样审阅指令文件、禁止修改配置与网络路由、保持沙盒与审批开启、巡检配置并及时轮换密钥。
什么是恶意 AGENTS.md 劫持攻击
恶意 AGENTS.md 是攻击者构造的项目指令文件,用来诱导编程 Agent 执行危险操作。Claude Code、Codex 等工具启动时都会自动加载当前目录下的这类文件。攻击不需要触发任何软件漏洞:Agent 只是按正常设计读入文件,并把它当成当前项目的工程规范执行。
打开看,它很像普通的工程说明:一段要求先安装某个依赖包的“前置检查(preflight)”,或一条修改 API 流量转发地址的“代理配置”。但在 Agent 眼里,这类指令和“使用 pnpm 而不是 npm”没有本质区别。
团队里有多位开发者同时跑编程 Agent 时,HiFox 可以统一派发任务与审阅改动;后文会说明这如何改变 Agent 的启动目录。
为什么编程 Agent 会乖乖听从这份文件
指令文件会直接进入 Agent 的上下文窗口,就排在你的提示词旁边,模型在“项目规则”和“你的真实指令”之间并没有一道硬性的信任隔离墙。
Claude Code 的记忆机制文档明确写道,CLAUDE.md 和 AGENTS.md 的内容会被当作“上下文而非强制配置”处理。当工作目录及上级目录中没有 CLAUDE.md 时,它会加载沿途所有的 AGENTS.md。Codex 的 AGENTS.md 指南同样说明,它会从项目根目录一路向下扫描到当前目录,按顺序拼接找到的指令文件(默认上限 32 KiB)。离启动位置越近的文件排在越后面,优先级也越高。换句话说,你在哪个文件夹里敲下启动命令,就决定了哪些文件会被读入,父级目录同样算数。
恶意 AGENTS.md 是如何劫持 Codex 与 Claude Code 的
2026 年 10 月 22 日,Forever Security 披露了他们在客户笔记本电脑上捕获的一起真实事件:一个编程 Agent 试图安装已知的恶意 npm 包 function-color,而这条安装指令正是来自 ~/Downloads 目录下的 AGENTS.md。Forever 在恶意代码真正运行前拦截了这次安装,但已无法追溯该文件最初是如何落入下载目录的。

为什么是 Downloads?因为浏览器网页不需要用户选择路径就能直接写入这个目录。Forever 随后完整复现了攻击链:
- 攻击者控制的网页将一份名为 AGENTS.md 的文件静默保存到
~/Downloads。 - 开发者在该目录下启动 Codex,并随手输入任何日常问题。
- 在正式处理任务前,Codex 按照文件要求向
~/.codex/config.toml写入了一个名为“project-tools”的服务器配置,并从 npm 安装指定软件包。 - 由于这份配置文件对整台电脑全局生效,此后无论开发者在哪个目录下启动 Codex,都会自动加载攻击者植入的服务。
Forever 报告称,Codex 在超过 90% 的测试中执行了载荷(多数测试使用只会打开计算器的无害替代包,真实恶意包仅在隔离虚拟机中运行过一次)。Claude Code 更难被直接诱导装包,但研究人员植入恶意 CLAUDE.md 后,成功把它的 API 请求地址改写到 Forever 控制的服务器上,泄露了 OAuth 登录令牌,攻击者服务器还能冒充大模型返回任意响应,该攻击在约 50% 的测试中触发。两项测试的载荷不同,百分比不宜直接对比。
Forever 的结论很明确:这不是靠厂商打补丁就能修好的软件 Bug,症结在于“把浏览器可以随意写入的目录,当成了受信任的代码目录”。Pillar Security 此前的「规则文件后门」研究也用过同一思路:在规则文件里塞入肉眼不可见的 Unicode 字符。
拦截恶意 AGENTS.md 的五步团队防护法
前两步负责把恶意文件挡在加载之前,后三步负责在指令不慎混入时锁死破坏半径。

1. 绝对不要在哪些目录启动编程 Agent?
永远不要在 ~/Downloads、用户主目录(~)或任何非你亲手创建的项目目录中启动 Agent。Forever 的遥测显示,大约一半的客户会在下载目录里运行编程 Agent。需要整理下载文件夹时,先把目标文件复制到新建的空白文件夹,再在那里启动。
为了防止团队成员一时疏忽,可以在 Shell 配置文件里加一道拦截护栏:
# ~/.zshrc:拒绝在网页可写入的目录中启动编程 Agent
agent_guard() {
case "$PWD" in
"$HOME"|"$HOME/Downloads"*|"/tmp"*)
echo "Refusing to start an agent in $PWD. Use a project folder." >&2
return 1 ;;
esac
}
claude() { agent_guard && command claude "$@"; }
codex() { agent_guard && command codex "$@"; }
2. 像审阅代码一样审阅 AGENTS.md
把每份指令文件当成可执行脚本,哪怕是你五分钟前刚克隆的仓库。再把审阅流程自动化:将所有指令文件路径写进 CODEOWNERS,任何修改都必须经指定负责人审批:
AGENTS.md @your-org/platform
**/AGENTS.md @your-org/platform
CLAUDE.md @your-org/platform
/.claude/ @your-org/platform
/.cursor/rules/ @your-org/platform
同时在 CI 中加入检查脚本,一旦发现这类攻击常用的特征(隐藏 Unicode 字符、修改基础 URL、在指令文件中内联安装命令)就直接报错拦截:
#!/usr/bin/env bash
# ci/check-agent-instructions.sh
files=$(git ls-files '*AGENTS.md' '*CLAUDE.md' '.cursor/rules/*')
[ -z "$files" ] && exit 0
fail=0
# 检查零宽字符、双向文本覆盖符与 Unicode 标签字符
if grep -nP '[\x{200B}-\x{200F}\x{202A}-\x{202E}\x{2066}-\x{2069}\x{E0000}-\x{E007F}]' $files; then
echo "Hidden Unicode in an agent instruction file"; fail=1
fi
if grep -niE 'BASE_URL|chatgpt_base_url|mcp_servers|(npm|pnpm|yarn) (install|add)|npx( --yes)? [a-z0-9@/_-]+|curl .*\| *(ba)?sh' $files; then
echo "Config, network or install instruction in an agent file: needs review"; fail=1
fi
exit $fail
第二条 grep 可能命中正常配置说明,这类改动本就值得人工多看一眼。
3. 禁止 Agent 改写自身配置文件
前面两起复现实验的最终落点,都是 Agent 动手修改了自己的配置文件。直接从权限上封死这条路。以 Claude Code 为例,可以在项目的 .claude/settings.json 中拒绝编辑 Agent 配置目录,并禁止读取本地环境变量文件:
{
"permissions": {
"deny": [
"Edit(./.claude/**)",
"Edit(~/.claude/**)",
"Edit(~/.codex/**)",
"Read(./.env)",
"Read(./.env.*)"
]
}
}
团队环境建议写入受管配置(managed settings),防止项目级文件放宽。记忆文档也建议用受管的 permissions.deny、sandbox.enabled 和 env 固化硬性要求,或配合 PreToolUse 钩子拦截高危操作;在受管 env 中锁死 API 路由,就能化解篡改 Base URL 的攻击。推广前请对照实际安装的客户端版本验证规则语法。
4. 保持沙盒与审批提示开启
Forever 建议始终开启审批关卡和沙盒隔离,并警惕任何要求 Agent 绕过审批的说明。
团队应明确哪些操作必须等待人工确认:安装新软件包、修改 Agent 配置文件、向陌生域名发起请求。人工拦截的节点设置见编程 Agent 审批关卡指南,权限划分原则见编程 Agent 的权限边界:它该碰什么,不该碰什么。
5. 巡检 Agent 配置文件并在命中时立即轮换密钥
Forever 给出了排查位置:检查 ~/.codex/config.toml 是否多出来历不明的 [mcp_servers.*] 配置块或被篡改的 chatgpt_base_url;检查全局及项目的 .claude/settings.json 是否有非你设置的 ANTHROPIC_BASE_URL、代理地址或陌生端点。
grep -nE '^\[mcp_servers\.|chatgpt_base_url' ~/.codex/config.toml
grep -rnE 'ANTHROPIC_BASE_URL|_PROXY|base_url' ~/.claude/settings.json .claude/settings*.json 2>/dev/null
npm ls -g --depth=0 2>/dev/null | grep -i function-color
npm ls --depth=0 2>/dev/null | grep -i function-color
find /tmp -maxdepth 5 -type d -name function-color 2>/dev/null
查出异常就假定令牌已泄露并立即轮换:被盗的 OAuth 令牌代表一个持续有效的登录会话,而不只是一次被拦截的请求。发现 function-color 时,直接把这台电脑视为已失陷主机。更完整的排查与轮换分工见我们同批整理的编程 Agent 密钥防泄露团队检查清单。
HiFox 在这套防护体系中的位置
HiFox 不替代代码扫描工具,也不取代 Agent 的权限配置(五步仍需落实)。它改变的是 Agent 从哪个目录启动、由谁决定。
在 HiFox 中,Agent 运行在你接入的电脑上,每个 Agent 在「运行设置」里配置默认工作目录。选「创建临时目录」时,每次运行都会分配独立临时目录,并基于绑定的代码库检出全新的 Git worktree;选「指定已有目录」时,运行只进入预先配置的本地路径。详见工作目录文档。
这就把“在哪个文件夹启动 Agent”从随手敲命令变成受控配置。在「创建临时目录」模式下,每次运行都从已绑定仓库的干净检出副本起步,不会误入某人刚打开的下载文件夹。空间 Git 仓库由空间管理员在空间设置中配置,Agent 自己的仓库由该 Agent 的管理者在 Agent 设置中配置。每次运行注入的 Agent 指令,也可以重申“严禁修改 Agent 配置文件”等准则。
运行结束后,改动与执行记录回传到任务卡片,形成可追溯的任务级证据。
总结
恶意 AGENTS.md 能得逞,是因为 Agent 按设计服从项目指令文件,而网页又能向日常信任的下载目录写入文件。防御它要靠多层护栏,而不是某个补丁。
建议今天先在每位开发者的电脑上跑一遍第 5 步的排查命令。团队如果已在并行使用多个编程 Agent,可以在 HiFox 中连接一台电脑并把 Agent 设为「创建临时目录」模式,让每次执行都从干净独立的 worktree 起步。
常见问题
恶意 AGENTS.md 能劫持 Claude Code 吗?
能。当工作目录及上级目录中没有 CLAUDE.md 时,Claude Code 会自动读取 AGENTS.md。在 Forever 的 Claude Code 复现实验中,研究人员利用植入的 CLAUDE.md 重定向了 API 流量,在约一半的测试中成功截获了 OAuth 令牌。
如何发现 AGENTS.md 里隐藏的恶意指令?
务必查看原始文本(Raw)而非渲染后的预览视图,并扫描文件中是否包含零宽字符、双向文本控制符和 Unicode 标签字符。上文给出的 CI 脚本会对这三类字符直接报错。
如果发现了来历不明的 AGENTS.md 该怎么办?
立即停止在该目录及子目录启动任何 Agent。检查 Agent 配置文件是否被添加了陌生的 MCP 服务器或 Base URL,排查是否安装了 function-color,然后立即轮换该 Agent 的登录令牌以及它能读取到的所有密钥。



