CVE-2026-102828 affects simple-git, the Node.js library that wraps the git command in a long list of tools: homegrown CI, changelog generators, repository bots, internal deployment platforms. Published by NVD on September 29, 2026, rated 9.8.
| Field | Value |
|---|---|
| CVSS 3.1 | 9.8 (CRITICAL) |
| Vector | AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H |
| NVD published | 2026-09-29 |
| Affected | 3.15.0 up to (excluding) 4.0.1 |
| Fixed in | 4.0.1 |
| CISA KEV | no (as of writing) |
What the Flaw Does
simple-git ships a default safeguard, blockUnsafeOperationsPlugin, meant to reject dangerous Git configuration options — the ones that make Git run an external command. The issue: the trailer.<token>.cmd family of keys was not classified as unsafe.
the default blockUnsafeOperationsPlugin does not classify
trailer.<token>.cmdas unsafe configuration.
So an application that lets user-controlled values reach SimpleGitOptions.config or inline -c arguments can lead Git to run a shell command chosen by the attacker. That command runs with the identity and permissions of the Node.js process.
The 9.8 assumes the worst case: an exposed application forwarding these values unfiltered. If your code never passes Git configuration derived from external input, you're not exposed through this path — but you should still upgrade.
The Real Lesson: Git Config Is Code
This CVE is the latest chapter of a familiar story. Git has several configuration options that name a command to execute: editor, pager, helpers, hooks, filters, and now trailers. Every library wrapping Git ends up maintaining a denylist of those options, and every denylist eventually misses one.
The rule to take away isn't "upgrade simple-git". It's:
never pass user-controlled Git configuration, whatever the library.
A branch name, a commit message, a repository URL are data. A Git configuration key or value is potentially a command.
Am I Affected?
- Find the installed version, including as a transitive dependency:
npm ls simple-git - Search your code for the
configoption when building the simple-git instance, and for calls adding-carguments. - Trace where the values come from: a constant, a deployed config file — or an HTTP request, a webhook, a user-supplied file?
The third case is the critical one. An internal tool that accepts "advanced Git options" from a web UI falls squarely into it.
Detection
- Unexpected child processes under the Node.js process: a shell or system binary spawned by
gitoutside the application's normal behaviour - Application logs: unusual Git configuration values received as input
- Outbound connections from the application host to unknown destinations
- Modified files in directories writable by the Node.js service account
Mitigation
- Upgrade simple-git to 4.0.1 or later, and regenerate the lockfile so transitive copies are covered.
- Remove every path by which external input reaches
SimpleGitOptions.configor a-cargument. If an option is genuinely needed, pick it from a closed server-side list — never copy it from the request. - Run the service with a minimal account: an injected command inherits its rights. No root, no unnecessary production secrets in the environment.
- Isolate Git operations on untrusted repositories (ephemeral container, read-only filesystem outside the working directory).
- Audit the other Git wrappers in your stack on the same principle: this class of flaw isn't specific to simple-git.
Why Continuous Dependency Monitoring Matters
simple-git almost never shows up in an inventory: it's tooling, often transitive, buried in scripts nobody considers exposed. That's exactly where a 9.8 stays open for months.
With cveo.tech, track the critical components of your applications and get alerted whenever a critical CVE affects them.