GitLost:我们如何欺骗GitHub的AI代理泄露私有仓库
攻击者通过创建看似无害的GitHub Issue,在Issue正文中隐藏恶意指令,利用GitHub Agentic Workflows的提示注入漏洞,使AI代理读取并公开泄露私有仓库内容。该漏洞无需攻击者具备编码技能或凭证,展示了代理AI系统中信任边界的根本性挑战。
GitHub 最近推出了 GitHub Agentic Workflows,将 GitHub Actions(GitHub 的自动化系统,用于响应仓库事件运行任务)与由 Claude 或 GitHub Copilot 支持的 AI 代理相结合。GitHub Agentic Workflows 允许团队用纯 Markdown 编写工作流,而 GitHub 代理则自行读取 Issue、调用工具并做出响应。
作为一名具有安全开发背景的漏洞研究员,该功能上线后最先浮现在脑海中的问题简单而根本:当 GitHub 代理读取到它不该信任的内容时会发生什么?答案是一种经典的间接提示注入攻击——这种攻击能够悄悄地将私有数据发送给互联网上的任何人。提示注入是一类攻击,攻击者将恶意指令隐藏在 AI 代理读取的内容中,使代理遵循这些隐藏指令而非操作者的指令。
GitLost 漏洞的根本原因在代理 AI 系统中已屡见不鲜:提示注入。在大多数代理提示注入攻击中,代理将错误的内容视为可信指令源,从而导致自身被误导或滥用。当系统无法在系统级指令与不可信的用户数据之间维持严格的信任边界时,就会发生这种情况。在本案例中,任何恶意行为者都可以创建一个 GitHub Issue,并在 Issue 正文中隐藏纯英语命令,GitHub 代理会遵循这些命令。
Noma Labs 发现的有漏洞的 GitHub Agentic Workflow 配置为:在 issues.assigned 事件触发工作流;读取 Issue 标题和正文;使用 add-comment 工具发布评论作为响应;对组织内的其他仓库(包括公共和私有仓库)拥有读取权限。利用此漏洞,攻击者无需编码技能、访问权限或凭证,只需在一个使用 GitHub Agentic Workflow 的组织所属的公共仓库中打开一个 Issue,然后等待即可。
攻击流程如下:首先,攻击者制作一个看似无害的 GitHub Issue,例如看起来像是销售副总裁与客户会面后的合理请求。然后,在 GitHub 自动化分配 Issue 后,事件触发的工作流使代理获取 README.md 的内容(来自公共仓库 poc 和私有仓库 testlocal)。最后,GitHub 代理将这些内容作为公共评论发布到公共仓库的 Issue 中,任何人都可以访问和阅读。
GitHub 设置了限制性防护措施来阻止此类情况,但未能按预期保护仓库。通过反复测试并添加关键词“Additionally”,攻击者触发了模型的意外行为,使其重新组织输出而不是拒绝。本质上,通过欺骗模型,攻击者确保了 GitHub 的防护措施无法正常工作,未能防止数据泄露。
GitLost 完美地说明了每个组织在代理 AI 系统中面临的基本安全挑战之一。代理的上下文窗口同时也是其攻击面。代理读取的任何内容——无论是 Issue、拉取请求、评论还是文件——如果代理将该内容视为指令输入,都可能被武器化。传统安全模型通常假设信任边界由代码强制执行。而在代理系统中,信任边界部分由模型行为强制执行,而模型天生具有指令跟随特性。对于代理 AI 来说,提示注入攻击已经变得像 SQL 注入对 Web 应用程序一样:一种系统性的、跨类别的漏洞类别,需要同样系统的策略和防御措施。
Noma 建议构建者和 AI 安全官员:永远不要将用户控制的内容视为 AI 代理的可信指令输入;将权限范围限制到最小,尤其是具有跨仓库访问权限的代理是高风险目标;限制代理公开发布的内容,尤其是响应 Issue 内容时;在将用户输入传递给模型之前,对其进行消毒或与指令上下文隔离。