FlawOpen

flawopen.com/AI Security/plugin4shell-ai-agent-plugin-sha-pin-bypass

● CWE-345 · 高危
安全研究 · FlawOpen

Plugin4Shell:插件 SHA 固定校验绕过

四种 AI 代理插件安装器固定了 Git 修订版,却未校验实际检出的 commit。Plugin4Shell 揭示了这一信任边界缺陷;应检查最终 SHA。[1]

💡 通俗易懂的原理解析 (ELI5)

图书馆按唯一目录号预留某个版本的书。工作人员按这个号码取书,却因为书架标签文字相同而交付了另一本。SHA 固定值就像目录号;安装器必须检查实际检出的 commit,确认一致后才能信任或运行插件。[1]

核心概念与专有名词

Commit SHA
用于标识特定 Git commit 对象的哈希。安全的版本固定流程必须将解析后的 checkout 与该值进行比较。[1], [2]
Git ref 歧义
Git 将对象 ID 和分支等名称都作为修订表达式处理。在某些情况下,看起来像 commit ID 的名称可能被解析为 ref。[1]
插件市场
分发代理扩展并记录已审查版本的目录。安装客户端仍须自行强制执行固定校验。[1]
CWE-345
数据真实性验证不足:系统使用数据前,没有充分确认其是否为预期的真实值。[5]

框架映射

  • 本指南所述弱点的 CWE 参考: CWE-345

攻击执行流程分解

步骤 1

市场记录已审查的 commit

插件条目指向一个仓库和一个具体 commit SHA,审查者期望安装器使用该版本。[1]

步骤 2

仓库控制者可以更改 ref

AIR Security 报告称,在允许此类名称的 Git 托管平台上,仓库控制者可创建与请求 SHA 同名的默认分支。报告还单独描述了 Gemini CLI 通过 FETCH_HEAD ref 解析的路径。[1]

步骤 3

安装器检出后未验证 HEAD

Codex 修复前将请求的 SHA 传给 <code>git checkout</code>,并把 Git 命令成功视为固定值已生效的证明。[1], [2]

步骤 4

客户端接受或拒绝实际检出的树

Codex 修复会在 checkout 后读取 <code>git rev-parse HEAD</code>,不匹配时立即终止。缺少等效检查时,被替换的插件代码可能以代理用户权限安装并运行。[2], [1]

源代码对比:漏洞与安全实现

有缺陷的路径把名称解析成功误当成对象身份已验证。补丁将最终 HEAD 与市场记录的固定值比较,并拒绝物化其他 commit。此代码对展示的是 Codex 补丁;其他产品的安装器实现不同,不能假定它们采用了相同修复。[2], [6]

存在漏洞的实现
// OpenAI Codex PR #34644 修复前的代码形态
if let Some(target) = sha.or(ref_name) {
    run_git(&["checkout", target], Some(destination))?;
}
// checkout 成功就被当作 SHA 匹配的证明。
加固后的安全修复
// Codex 修复:验证实际解析出的 commit,而不只是请求参数
if let Some(sha) = sha {
    run_git(&["checkout", sha], Some(destination))?;
    let checked_out_sha =
        run_git_output(&["rev-parse", "HEAD"], Some(destination))?;
    if !checked_out_sha.eq_ignore_ascii_case(sha) {
        return Err(format!(
            "checked out Git SHA {checked_out_sha} does not match requested SHA {sha}"
        ));
    }
} else if let Some(ref_name) = ref_name {
    run_git(&["checkout", ref_name], Some(destination))?;
}

工程与系统安全加固清单

参考来源

← AI Security Directory →