When a repository's git config runs code: ConfigPoisoning and coding agents
GitLab researchers showed a coding tool running attacker code from a repository's own git filters. Why deny-lists fail, and what to ask of tools that run git.
Coding agents and the tools around them run git all the time, in whatever directory a developer opens. On 2 October 2026 GitLab's Threat Research Group published a vulnerability it calls ConfigPoisoning in DeepSeek-Reasonix Studio, a desktop git client built for developers working with AI coding assistants. Viewing a file's diff could run a command chosen by whoever wrote the repository's configuration. The tool is niche; the lesson is not. GitLab says several widely used coding agents have the same class of flaw, under coordinated disclosure, and that this is the first case it is publishing in full.
The mechanism
Git lets configuration run programs as part of ordinary operations. The gitattributes documentation describes filter drivers: a clean command that converts a working-tree file "upon checkin", and a smudge command used on checkout. The .gitattributes file assigns a driver to files by path, and the driver's commands are defined in git configuration. Other keys work the same way: core.fsmonitor, core.hooksPath, diff.external, a diff driver's textconv, core.sshCommand, core.pager and core.editor can all name a program to run.
Reasonix knew this. According to the project's advisory, its git wrapper set core.fsmonitor=false and maintenance.auto=false on every call and added --no-ext-diff and --no-textconv to diffs. It did not cover filter drivers, and its own code comment named that gap. When the desktop app showed the diff of a changed file, git ran the file's clean filter to build the comparison, and none of the flags above touch that step. GitLab found the command ran once for each side of the diff. git status didn't trigger it, which isolated the bug to the diff view.
The reason the gap stayed open is instructive. The other keys have fixed names, so a wrapper can override them. A filter driver's name is whatever .gitattributes says, so a fixed deny-list cannot cover it. You have to read the attributes and override every driver they mention, or avoid the filter machinery altogether.
How a poisoned config arrives
The attack needs two files. The .gitattributes entry survives a normal git clone; the .git/config that defines the driver does not, because cloning doesn't copy local configuration. That is why GitLab notes that repositories hosted on its platform aren't affected: cloning over HTTPS or SSH doesn't transfer local configuration files.
The advisory lists the realistic delivery routes: an archive or tarball, a synced or shared folder, a CI cache, or a devcontainer image built with COPY . .. GitLab adds a route specific to agentic tooling: a rogue, compromised or prompt-injected agent already running on the developer's machine has the developer's filesystem access, and can write the poisoned .git/config into a repository that was cloned perfectly normally. Another extension or process with the same permissions could do the same.
Fixed versions, and where the sources differ
The fix is in Reasonix Studio 2.21.0 and the npm package 1.39.3. Both GitLab and the advisory rate the flaw critical; the advisory gives no CVSS score.
A few details differ between the two sources:
- Dates. GitLab's timeline says the fix shipped and the advisory was published on 30 September. The advisory page shows it published on 29 September (UTC).
- CVE. GitLab cites CVE-2026-102437. The advisory record lists no CVE ID.
- Package name. GitLab writes "
DeepSeek Reasonixnpm"; the advisory lists the npm package asreasonix, affected below 1.39.3.
None of these change what to do, but if you track this by CVE, check that your scanner has the ID before relying on it.
Why coding agents make this worse
Plain git clients already carry advisories for configuration-driven execution. GitLab's point is that coding agents change the exposure in three ways.
First, agents run git constantly and automatically: status checks, diffs to show the user, diffs fed to the model, commits. The developer doesn't choose each command, so they can't decide to skip a risky one.
Second, every tool wraps git its own way, and, in GitLab's words, "each one tends to close only the primitive that caused its own last incident". A tool that hardened against core.fsmonitor after one report may be open to filter.*.clean or core.sshCommand.
Third, tools treat repository files as their own settings. GitLab saw the same mistake earlier in the year in another AI coding tool that ran code from a project configuration file when a repository was opened. The pattern repeats: a file the repository's author controls, read as if the tool's user had written it. It is the same class of problem as instruction files and hooks committed to a repository, which Singapore's CSA lists among its baseline attack vectors in its new handbook for coding assistants. On Windows, Claude Desktop's recent search-path flaw, covered in three Claude advisories in October, was a different bug with the same trigger: opening a project that contained a file someone else put there.
What it means for engineering and security leaders
- Ask vendors how they neutralise repository-local configuration, not only how they handle untrusted remotes. That is GitLab's recommendation, and it is a good question for every coding agent, git client and editor extension you approve.
- Treat anything that wasn't a fresh clone as untrusted: archives, shared folders, CI caches, devcontainer builds that copy the working tree, and repositories an agent has had write access to.
- Inventory tools that shell out to git on developer machines. Each one runs with the developer's full access.
Practical takeaways
- If you use Reasonix, update to Studio 2.21.0 or npm 1.39.3. On older versions, don't diff repositories you didn't clone yourself, as GitLab advises.
- Check local git configuration for programs you didn't set, for example:
git config --local --list | grep -Ei 'filter\.|fsmonitor|hookspath|textconv|external|sshcommand|pager|editor'
- If you build tools that run git against directories you don't control, follow the advisory and GitLab's guidance: read blob contents with
git cat-fileorgit showand diff in-process; if you must shell out, override every relevant key on every call, includingfilter.<name>.cleanandsmudgefor every driver named in.gitattributes,.git/info/attributesand global or system files; and remember that one flag doesn't cover another (--no-ext-diffdoes nothing forcore.sshCommand). - Add a test with a deliberately hostile
.gitattributesand.git/configpair before you ship. - Build devcontainer images from a clean checkout rather than copying a working tree that includes
.git.