文章总结: DARKNAVY团队对ClaudeCode、OpenAICodex和Cursor三款AI编程助手进行安全测试,发现其在可信项目环境下均可被诱导绕过工具执行层安全机制。攻击核心在于利用权限检查与实际Shell执行间的语义差异,例如通过Zsh的$=参数展开语法绕过ClaudeCode的静态检测,实现未授权代码执行。研究表明AIAgent安全边界需强化执行层防护而非依赖模型自律。 综合评分: 85 文章分类: AI安全,漏洞分析,安全工具,红队,渗透测试
我们试着把干掉黑客的AI干掉了|前瞻对抗
原创
前瞻对抗 前瞻对抗
DARKNAVY
2026年5月12日 15:00 上海
在小说阅读器读本章
去阅读
2025 年 5 月,DARKNAVY 内部自研的 AI Agent 发现了首个公开披露的 Linux 内核可利用 0day 漏洞。彼时,AI 已经开始进入高阶安全研究流程,但它更多仍是人类研究员手中的工具,需要在专业指导之下发挥作用。
一年之间,AI 在安全研究领域的能力快速跃升,从 Anthropic 的 Claude Mythos Preview,到 OpenAI 的 Codex Security,AI 在漏洞发现、漏洞验证乃至补丁生成中,已经能完成相当一部分过去需要安全研究员手动处理的工作。进入 2026 年后,研究员不再逐行审计代码,而是通过简单的任务描述,将大部分搜索、分析和验证过程交给 AI 完成。AI 正在从辅助工具变成安全研究的直接参与者,甚至开始被认为可能取代人类安全研究员。
于是,一个更尖锐的问题随之出现:当 AI 开始替代人类黑客去发现漏洞时,AI 自己是否经得起同样的安全检验?
这一次,DARKNAVY 选择反过来挑战 AI 厂商最核心、也最具代表性的产品形态:AI Coding Agent。我们选择了 Claude Code、OpenAI Codex 和 Cursor 作为研究对象,它们是当下最受关注的 AI 编程助手,能够读取项目文件、理解代码上下文、访问网络、调用工具、执行命令,与开发者的真实工作环境深度绑定。
DARKNAVY 团队近期对这三款 AI Coding Agent 进行了系统性的攻防测试。结果是,在空白项目、默认配置、无需任何额外用户批准的最简前提下,三者均被成功攻破。
已关注
关注
重播 分享 赞
关闭
观看更多
更多
退出全屏
切换到竖屏全屏退出全屏
DARKNAVY已关注
分享视频
,时长01:26
0/0
00:00/01:26
切换到横屏模式
继续播放
[ ]
进度条,百分之0
播放
00:00
/
01:26
01:26
倍速
全屏
倍速播放中
0.5倍 0.75倍 1.0倍 1.5倍 2.0倍
超清 流畅
继续观看
我们试着把干掉黑客的AI干掉了|前瞻对抗
观看更多
原创
,
我们试着把干掉黑客的AI干掉了|前瞻对抗
DARKNAVY已关注
分享点赞在看
已同步到看一看写下你的评论
视频详情
AI Coding Agent 的攻击场景
在 AI Coding Agent 的实际使用中,针对它们的攻击可以粗略分为两类。
1
恶意项目场景
用户从不可信来源获取了一个被精心构造的项目,例如 GitHub 仓库、社群分享、邮件附件或钓鱼链接,并使用 AI Coding Agent 打开它。在用户尚未明确授权信任当前工作区之前,本地环境就已经被攻陷。
这一类攻击的本质,是利用 Agent 在项目加载和初始化阶段的逻辑缺陷。DARKNAVY 此前在 OpenAI Codex 桌面端发现的零授权代码执行漏洞,就属于这一类问题。
不过,这类攻击的防御责任目前处于厂商和用户之间的模糊地带。常见的 AI Coding Agents 并未提供面向恶意项目威胁的充分防护,而是默认将风险转嫁给用户:打开任何文件夹之前,用户需自行确认其中内容是否安全。在我们的测试中,通过打开恶意项目实现未授权代码执行的路径非常多,技术门槛并不高。在厂商将此类场景纳入自身安全边界之前,本文不展开讨论。
2
可信项目下的诱导攻击
用户在自己长期维护、完全信任的项目目录中工作,Coding Agent 也运行在用户已经授权的环境内。在这个过程中,用户出于正常开发需求,让 Agent 访问某些外部资源。它可能是一份开发文档、一个依赖包、一个 issue、一段网页内容,或任何看起来与当前任务相关的网络信息。
就在这一刻,Agent 被诱导执行了恶意操作,并且绕过了 Coding Agent 内置的多层安全检查,最终导致用户电脑被攻陷。
这正是我们这次真正关心的场景,也是文章开头三段视频所演示的场景。在这个场景里,用户并没有做错任何事情。他只是在自己信任的项目中,让 AI 自己学习一份资料,理解一段代码,或者完成一次正常的开发任务。
也就是说,用户对 Agent 的每一次信任,都可能被攻击者转化为新的入口。
不只是提示注入
在 AI Agent 安全的讨论中,提示注入(Prompt Injection)几乎成了一个被滥用的术语。一听到 Agent 被攻破,很多人会自动归因为又是一次 Prompt Injection。
然而,在我们这次研究的攻击链中发现,Prompt Injection 并不是最关键的环节。它最多只是让模型产生某种行为意图,而真正决定攻击是否能够落地的,是工具执行层的安全边界是否有效。
要理解这一点,需要先明确一个基础事实:现代 AI Coding Agent 通常都内置了多层安全机制。以 Claude Code 为例,其官方文档[1]描述了一种 permission-based architecture。只读类操作可以默认允许,但凡涉及文件修改、测试运行、命令执行等敏感动作,都需要经过独立的权限校验和用户确认。
因此,真正可控的安全边界,并不在于模型被说服了什么,而在于执行层是否真的能够拦截危险操作。
模型可以决定它想做什么,但敏感工具的实际执行,尤其是 bash 命令执行,应该当由权限检查、沙箱隔离或者二者组合来强制约束。无论具体实现如何,它都应该是确定性的代码逻辑,而不是依赖模型自觉遵守规则。
为了更直观地说明这一点,我们做了一组对比演示。
- 左侧窗口中,我们直接要求 Agent 执行一个敏感命令,例如打开计算器。此时,Agent 按照预期被安全机制拦截,或者弹出确认窗口,要求用户明确批准。
- 右侧窗口中,我们通过构造输入,触发相关漏洞,让 Agent 最终执行同样的敏感行为。不同的是,整个过程中没有任何弹窗,没有任何用户批准,敏感命令被直接静默执行。
左:敏感命令需要用户授权 右:利用漏洞构造输入绕过用户授权
两个窗口里 Agent 的最终行为完全相同,但一个被安全机制拦截,一个执行成功。这之间的差别,问题不只是 Prompt Injection,而是 Prompt Injection 之后,原本应该作为最后防线的执行安全边界被穿透了。
这才是我们这次研究真正想揭示的问题。
攻击链的核心:突破工具执行边界
三款 Agent 在工具执行这一层有着不同的侧重:Claude Code 依赖权限检查作为主要防线,默认不启用沙箱;Codex 和 Cursor 则以沙箱作为最终兜底。接下来,我们将分析这两套机制的实现原理和薄弱点。
Claude Code:绕过权限检查
Claude Code 默认不启用沙箱,其工具执行的安全完全依赖于一套权限检查系统——敏感命令在执行前必须经过权限校验或弹窗确认。
从实现上看,Claude Code 在执行 Bash 工具调用前,会先对要执行的命令字符串进行静态解析,尝试从用户输入中识别出将要执行的可执行文件及其参数,并根据解析结果判断该命令是否需要用户授权。默认情况下,只有被判定为“安全”的只读命令,才能在无需用户确认的情况下直接执行;其他命令,都应进入用户授权流程。
首先,Claude Code 会检查命令中是否包含危险操作、特殊语法或高风险模式。例如,某些重定向、管道、命令替换等模式可能会被识别为敏感行为,从而要求用户显式授权后才能执行:
const COMMAND_SUBSTITUTION_PATTERNS = [ { pattern: /<\(/, message: 'process substitution <()' }, { pattern: />\(/, message: 'process substitution >()' }, { pattern: /=\(/, message: 'Zsh process substitution =()' }, { pattern: /(?:^|[\s;&|])=[a-zA-Z_]/, message: 'Zsh equals expansion (=cmd)' }, { pattern: /\$\(/, message: '$() command substitution' }, { pattern: /\$\{/, message: '${} parameter substitution' }, { pattern: /\$\[/, message: '$[] legacy arithmetic expansion' }, { pattern: /~\[/, message: 'Zsh-style parameter expansion' }, { pattern: /\(e:/, message: 'Zsh-style glob qualifiers' }, { pattern: /\(\+/, message: 'Zsh glob qualifier with command execution' }, { pattern: /\}\s*always\s*\{/, message: 'Zsh always block (try/always construct)' }, { pattern: /<#/, message: 'PowerShell comment syntax' },]
此外,如果命令字符串中包含控制字符,Claude Code 也会将其视为不安全输入,并要求用户授权。这类检查通常用于防止攻击者通过不可见字符、终端控制序列或其他非打印字符隐藏真实命令意图,从而绕过基于字符串的安全判断:
if (CONTROL_CHAR_RE.test(command)) { logEvent('tengu_bash_security_check_triggered', { checkId: BASH_SECURITY_CHECK_IDS.CONTROL_CHARACTERS, }) return { behavior: 'ask', message: 'Command contains non-printable control characters that could be used to bypass security checks', isBashSecurityCheckForMisparsing: true, }}
在确认命令中不包含上述危险元素之后,Claude Code 会进一步判断该命令是否仅执行只读操作。为此,它维护了一组只读命令及其允许参数的白名单。只有当命令名称位于白名单中,并且其参数也完全符合对应命令的允许范围时,该命令才会被视为只读。
例如,对于 base64 这类命令,Claude Code 并不会简单地允许任意参数组合,而是只允许例如控制解码模式或输出格式的部分选项:
base64: { respectsDoubleDash: false, // macOS base64 does not respect POSIX -- safeFlags: { // Safe decode options '-d': 'none', // Decode '-D': 'none', // Decode (macOS) '--decode': 'none', // Decode
// Safe formatting options '-b': 'number', // Break lines at num (macOS) '--break': 'number', // Break lines at num (macOS) '-w': 'number', // Wrap lines at COLS (Linux) '--wrap': 'number', // Wrap lines at COLS (Linux)
// Safe input options (read from file, not write) '-i': 'string', // Input file (safe for reading) '--input': 'string', // Input file (safe for reading)
// Safe misc options '--ignore-garbage': 'none', // Ignore non-alphabet chars when decoding (Linux) '-h': 'none', // Help '--help': 'none', // Help '--version': 'none', // Version },}
这种设计的安全边界建立在一个前提之上:权限检查阶段解析出的命令名称和参数,必须与实际执行阶段 Shell 最终解释并运行的内容保持一致。一旦两者之间存在语义差异,就可能产生权限绕过风险。
例如在 Claude Code < v2.1.132 的版本中,我们发现权限检查逻辑并未识别 Zsh 中的 $= 参数展开语法。
Claude Code 会调用系统默认 Shell 执行 Bash 工具中的命令。在 macOS 环境下,默认 Shell 通常是 Zsh。Zsh 的 $= 语法会对变量展开后的结果再做一次无视引号的参数拆分:如果变量包含空格,$=var 不会作为单个参数传入,而是被拆成多个独立参数。
这就在权限检查和实际执行之间制造了语义差异:Claude Code 基于原始命令字符串做静态匹配,看到的是一个参数;而 Zsh 实际执行时拆出的是多个参数。攻击者可以把不安全的内容藏在变量里,让权限检查阶段看起来仍然符合只读命令的白名单。
以 uniq 命令为例。Claude Code 使用如下正则判断 uniq 是否属于可无授权执行的安全只读命令:
而一个完整的uniq命令语法如下:
uniq [-cdiu] [-D[septype]] [-f num] [-s chars] [input_file [output_file]]
可以看到,Claude Code 的白名单正则只允许部分安全选项,例如用于控制比较行为、跳过字段或跳过字符数量的参数,并不允许用户显式指定输入文件和输出文件。
由于旧版本没有处理 Zsh 的 $= 展开语义,攻击者可以构造如下形式的命令:uniq --skip-chars="1$=A",这条命令会被 Claude Code 视为对 uniq 的一次普通参数调用,并在无需用户授权的情况下执行。
但在 Zsh 的真实执行阶段,如果变量 A 的值为:A=' 1.txt 2.txt',那么 $=A 触发参数拆分后,使最终执行的命令等价于:uniq --skip-chars=1 1.txt 2.txt。Claude Code 对实际执行的内容误判,导致了最终对文件 2.txt 的非预期写入。
通过设置 $HOME/.claude/settings.json 为 uniq 的写入目标,可以在用户无授权的情况下修改 Claude Code 的配置文件,并实现命令执行。
使用上述漏洞绕过 Claude Code 的命令权限检查
该漏洞已在 v2.1.132 进行了修复,新版本在检测到相关 Zsh 参数展开语法时,会将命令识别为高风险输入,并提示:zsh $+/$^/$=/$~ prefix-flag expansion — value defeats downstream content checks,需要用户授权后才能执行。
Codex 与 Cursor:逃逸沙箱
Codex 和 Cursor 的工具执行默认运行在一个受限的沙箱环境中,理论上即便 Agent 被诱导执行恶意命令,也会被沙箱限制在一个隔离的执行域内。
Codex 和 Cursor 并没有采用虚拟机或容器级别的完整隔离方案,而是复用了不同操作系统自身的访问控制机制,并在此基础上使用基于文件路径和网络等规则的策略。例如在 macOS 上,这两个 AI Agent 均使用了 Apple Seatbelt 运行时沙箱,通过动态生成配置文本的方式,限制工具进程的文件系统、网络和进程相关权限。
在工具执行前,AI Agent 会基于一套默认沙箱规则,并结合用户配置、当前工作目录以及工具调用所需的权限,动态生成最终的运行时访问策略。以 Codex 为例,其默认沙箱规则会允许程序正常启动和执行,同时放行对部分系统目录、系统库以及运行时依赖文件的访问,以保证常见命令和开发工具能够在沙箱内正常运行:
(deny default)
; child processes inherit the policy of their parent(allow process-exec)(allow process-fork)(allow signal (target same-sandbox))
; process-info(allow process-info* (target same-sandbox))
; ......(allow file-read* file-write* file-ioctl (literal "/dev/ptmx"))(allow file-read* file-write* (require-all (regex #"^/dev/ttys[0-9]+") (extension "com.apple.sandbox.pty"))); ......
随后,在默认配置下,Codex 会进一步放行当前项目目录以及临时目录中的写入操作。这样设计的目的是让 Agent 可以在沙箱中完成代码修改、构建产物生成等常见开发任务:
let mut entries = vec![ FileSystemSandboxEntry { path: FileSystemPath::Special { value: FileSystemSpecialPath::Root, }, access: FileSystemAccessMode::Read, }, FileSystemSandboxEntry { path: FileSystemPath::Special { value: FileSystemSpecialPath::project_roots(/*subpath*/ None), }, access: FileSystemAccessMode::Write, },];
与此同时,Codex 也会对当前目录下的一些敏感元数据目录设置更严格的访问策略。例如,对于 .git、配置目录、依赖管理元数据或其他可能影响项目状态与供应链安全的路径,沙箱策略会将其限制为只读。这样可以在允许 Agent 修改项目代码的同时,降低其篡改版本历史、Git 配置等的风险:
const PROTECTED_METADATA_GIT_PATH_NAME: &str = ".git";const PROTECTED_METADATA_AGENTS_PATH_NAME: &str = ".agents";const PROTECTED_METADATA_CODEX_PATH_NAME: &str = ".codex";
整体来看,这类沙箱并不是一个完全独立的执行环境,而是一个基于宿主操作系统访问控制能力构建的“受限进程环境”。它的安全性高度依赖动态生成的策略是否完整、路径匹配是否准确、黑白名单边界是否清晰,以及工具执行框架是否始终确保命令在预期的沙箱配置下运行。一旦策略生成、路径解析或权限豁免逻辑中存在偏差,攻击者就可能利用这些差异突破 Agent 设计者预期的隔离边界。
例如,在 Codex < v0.126.0 的版本中,我们发现 Codex 只有在当前工作目录本身已经存在 .git 目录时,才会将其识别为需要特殊保护的 Git 元数据目录,并对其访问进行限制。
let top_level_git = writable_root.join(PROTECTED_METADATA_GIT_PATH_NAME);// This applies to typical repos (directory .git), worktrees/submodules// (file .git with gitdir pointer), and bare repos when the gitdir is the// writable root itself.let top_level_git_is_file = top_level_git.as_path().is_file();let top_level_git_is_dir = top_level_git.as_path().is_dir();let should_protect_top_level = top_level_git_is_dir || top_level_git_is_file;if should_protect_top_level { if top_level_git_is_file && is_git_pointer_file(&top_level_git) && let Some(gitdir) = resolve_gitdir_from_file(&top_level_git) { subpaths.push(gitdir); } subpaths.push(top_level_git);}
如果当前工作目录在执行命令前不存在 .git,Codex 便不会提前对 Git 元数据路径建立只读的沙箱规则。此时,攻击者可以先通过沙箱内的工具执行,在当前目录下创建一个伪造的 .git 目录,并进一步写入恶意的 Git hooks。
这一点破坏了 Codex 沙箱模型中的关键假设。Codex 每次在对话过程中会在沙箱外执行 Git 相关操作,这些操作使用了受限沙箱内的配置文件,因此对应的 hooks 能够在沙箱外执行任意命令。
使用上述漏洞在 Codex 沙箱外执行命令
该漏洞已在 v0.126.0 进行了修复,即使工作目录不存在.git,也会在沙箱规则中将其默认设置为只读,不再能通过这种方式进行沙箱外的命令执行。
总而言之,权限检查与沙箱,是当代 Coding Agent 在工具执行层的两种主要防御范式。我们的研究表明,这两种范式在实现层面都存在可被穿透的缺陷,一旦构造出可触发的输入,权限绕过或沙箱逃逸的执行就是确定性的。这类漏洞和过去二十年在浏览器、操作系统、虚拟化环境中反复出现的经典缺陷本质相同,只是 Agent 的出现让它在一个新的场景里被重新放大。
需要说明的是,除了本文披露的问题之外,我们针对这三款 Coding Agent 还发现了若干其他漏洞,文章开头视频中演示的完整攻击链正是基于这些漏洞构造。相关问题仍在与厂商的负责人披露流程中,尚未完成修复,本文暂不公开技术细节,待修复完成后再行公开。
结语
我们有理由相信:本文涉及的这些模型厂商自研的 AI Coding Agent,在发布之前,很可能已经接受过它们内部最先进的 AI 安全审查。
也正因为如此,这次研究才更值得被讨论:当 AI 开始取代人类黑客的工作,AI 系统自身是否仍然需要接受人类黑客的真实对抗?
我们的回答是:需要,而且必须。
AI 更擅长的,是在已知代码库、漏洞模式和攻击面上进行自动化、规模化覆盖。但真正突破性的安全研究,往往诞生于未知的边界:攻击者可能会用系统设计者从未预料的方式,将多个看似无害的组件、权限和信任关系串联起来,形成一条新的攻击链。这是当前 AI 仍然难以完全替代人类研究员的部分。
或许有一天,AI 也能完成这种创造性的对抗推演。但在那之前,AI 自身的安全,仍然需要人类黑客作为最后一道检验。
AI 正在改变黑客。但至少现在,黑客仍然可以改变 AI。
本文相关漏洞在官方修复发布前,恕不公开任何具体技术细节。
预告
AI 干掉黑客,还是黑客干掉 AI?
我们从未停止好奇,如果有一天 AI 终将失控,
黑客会是最后一道防线吗?
10.24 上海西岸
GEEKCON 2026
邀您一起寻找答案
参 考:
[1] https://code.claude.com/docs/en/security#permission-based-architecture
[2] https://developers.openai.com/codex/agent-approvals-security
[3] https://cursor.com/docs/agent/security
免责声明:
本文所载程序、技术方法仅面向合法合规的安全研究与教学场景,旨在提升网络安全防护能力,具有明确的技术研究属性。
任何单位或个人未经授权,将本文内容用于攻击、破坏等非法用途的,由此引发的全部法律责任、民事赔偿及连带责任,均由行为人独立承担,本站不承担任何连带责任。
本站内容均为技术交流与知识分享目的发布,若存在版权侵权或其他异议,请通过邮件联系处理,具体联系方式可点击页面上方的联系我。
本文转载自:DARKNAVY 前瞻对抗 前瞻对抗《我们试着把干掉黑客的AI干掉了|前瞻对抗》
版权声明
本站仅做备份收录,仅供研究与教学参考之用。
读者将信息用于其他用途的,全部法律及连带责任由读者自行承担,本站不承担任何责任。











评论