GitSpawn:不受信任的存储库可通过 AI 编程代理执行代码
GitSpawn: Untrusted repos can execute code via AI coding agents

原始链接: https://www.manifold.security/blog/ai-coding-agents-git-hijack

研究人员发现了一个被称为“GitSpawn”的关键安全漏洞,该漏洞影响了众多 CLI AI 智能体(包括 Claude Code、Goose 等)。 该问题源于这些智能体在启动时会自动运行标准 Git 命令(如 `git status`)以收集项目上下文。这些命令会触发 Git 的“索引刷新”(index refresh),进而无意中执行存储库本地 `.git/config` 文件中定义的配置命令。具体而言,`core.fsmonitor` 等功能允许存储库指定一个命令,该命令会在任何安全沙箱或批准提示介入之前,以用户完全权限在主机系统上执行。 此漏洞极其危险,因为恶意配置并非由标准的 `git clone` 触发,而是通过打开经由 ZIP 文件、共享驱动器或 USB 获取的存储库触发。由于 AI 智能体自身在内部沙箱之外启动了 Git 进程,因此恶意命令会在主机上透明地运行。研究人员强调,这种模式在 AI 智能体生态系统中非常普遍,它使日常的 Git 操作成为了未经授权远程代码执行的攻击媒介。

Hacker News 最新 | 过往 | 评论 | 提问 | 展示 | 招聘 | 提交 登录 GitSpawn:不可信代码仓库可通过 AI 编程代理执行代码 (manifold.security) 4 分,由 fourfire 发布于 2 小时前 | 隐藏 | 过往 | 收藏 | 2 条评论 grncdr 4 分钟前 | 下一条 [–] > Git 会从代码仓库自身的 .git/config 中读取该设置。因此,一个代码仓库可以包含以下内容: 随后: > 关于交付方式的精确性非常重要,因为 git 本身永远不会携带这些内容。克隆恶意 URL 不会产生任何影响,fetch 或 pull 也一样。 全是 AI 的垃圾废话。这个所谓的“漏洞”与代码代理毫无关系。 回复 DivingForGold 33 分钟前 | 上一条 | 下一条 [–] GitSpawn:一个让不可信仓库在 Claude Code、Codex、Cursor 和 Grok 中运行代码的漏洞 回复 准则 | 常见问题 | 列表 | API | 安全 | 法律 | 申请 YC | 联系 搜索:
相关文章

原文

This research began with a single question: what does a CLI AI agent actually do when it starts up? What happens under the hood?

Upon looking at several AI agents, we observed the same behaviour, they gather context about the project they have just been opened in. A good part of that gathering is done with git, called for different purposes at different moments, some on start-up, some once the session begins.

Looking at how git is used, we found a vulnerable pattern. Those context-gathering calls ran without stripping the repository's own git configuration, and several git settings are command execution sinks. The repository names a command, git runs it, on the host, with the user's privileges, before any approval prompt.

This post covers only a few of them, Claude Code, Goose, Grok Build, Hermes and Qwen Code. We found it in more agents than we name here.

What an agent asks git for depends on what it is trying to do. It might want the current branch, and which files have been modified or staged. It might want the files a change touched, or every path the repository tracks, or a fresh worktree for a sub-agent to work in.

Two samples out of many, from different products:

git status --porcelain=2 --branch

git diff --name-only HEAD

Neither is unusual. Both are the sort of command you would write yourself. And both, like most git commands that touch the working tree, make git refresh its index first.

That refresh is the sink.

core.fsmonitor is a performance setting for large repositories. Instead of checking every file on disk, git asks a helper program what changed, and runs it during an index refresh. Documented, intended behaviour.

Git reads that setting from the repository's own .git/config. So a repository can ship this:

[core]

    fsmonitor = <command>

and any git command that refreshes the index runs it: git status, git diff. Which one the agent chose does not matter. And core.fsmonitor is not the only setting of its kind, which is why one of the findings below is not a core.fsmonitor bug at all.

Delivery is worth being precise about, because git never carries this. Cloning a hostile URL does nothing, and neither does fetch or pull. The repository has to arrive as files with its .git directory already inside, so the vector is anything that moves a directory instead of cloning it: a shared .zip, a shared drive, a sync folder, a USB stick. Colleagues pass projects around this way, consultants hand them to clients. For every proof of concept in this post, we used a .zip.

From there the command runs as you, with your privileges, on your machine. This is the agent's own code spawning a subprocess to use git, so the command runs outside the sandbox, without an approval prompt. The permission model never sees it.

We call it GitSpawn. Below are examples of what we found, in different CLI AI agents.

联系我们 contact @ memedata.com