CVE-2026-63475: CVE-2026-63475: Persistent Denial of Service via Circular Symbolic References in isomorphic-git
CVE-2026-63475: Persistent Denial of Service via Circular Symbolic References in isomorphic-git Vulnerability ID: CVE-2026-63475 CVSS Score: 4.3 Published: 2026-11-09 CVE-2026-63475 (GHSA-96wc-2m84-2cj7) is an uncon
CVE-2026-63475: Persistent Denial of Service via Circular Symbolic References in isomorphic-git
Vulnerability ID: CVE-2026-63475
CVSS Score: 4.3
Published: 2026-11-09
CVE-2026-63475 (GHSA-96wc-2m84-2cj7) is an uncontrolled recursion and infinite loop vulnerability in isomorphic-git prior to version 1.38.6. When processing Git protocol responses from a malicious or man-in-the-middle (MitM) server, isomorphic-git writes server-advertised symbolic reference (symref) capabilities directly to the local repository filesystem without validating for circular dependencies. Because the reference resolution logic in GitRefManager.resolve() lacks both cycle detection and a default recursion depth limit, any subsequent operation that resolves the circular references enters a non-terminating asynchronous recursion loop. Because the malicious references are persisted on disk, this condition induces a persistent denial of service (DoS) against the affected repository.
TL;DR
Versions of isomorphic-git prior to 1.38.6 fail to detect circular symbolic references during ref resolution in GitRefManager.resolve(). Cloning or fetching from a malicious Git remote that advertises mutually referential symref capabilities writes circular reference files to disk, causing subsequent Git operations (checkout, log, status, branch) to hang indefinitely.
⚠️ Exploit Status: POC
Technical Details
- CVE / GHSA ID: CVE-2026-63475 / GHSA-96wc-2m84-2cj7
- Weakness Class: CWE-674 (Uncontrolled Recursion) / CWE-835 (Infinite Loop)
- CVSS v3.1 Score: 4.3 Medium (CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:N/I:N/A:L)
- EPSS Score: 0.40% (34.33rd percentile)
- Affected Component: GitRefManager.resolve() & updateRemoteRefs in isomorphic-git < 1.38.6
- Primary Impact: Persistent Denial of Service (non-terminating async recursion on repository access)
- Exploit & KEV Status: PoC Available (Unit Test) / Not Listed in CISA KEV
Affected Systems
- isomorphic-git (Node.js and browser environments)
-
isomorphic-git: < 1.38.6 (Fixed in:
1.38.6)
Code Analysis
Commit: 823843d
fix: fixing git internals (PR #2370) - Add cycle detection via visited Set in GitRefManager.resolve()
diff --git a/src/managers/GitRefManager.js b/src/managers/GitRefManager.js
@@ -3,6 +3,7 @@ import '../typedefs.js'
// This is a convenience wrapper for reading and writing files in the 'refs' directory.
import AsyncLock from 'async-lock'
+import { InternalError } from '../errors/InternalError.js'
import { InvalidOidError } from '../errors/InvalidOidError.js'
import { NoRefspecError } from '../errors/NoRefspecError.js'
import { NotFoundError } from '../errors/NotFoundError.js'
@@ -255,7 +256,13 @@ export class GitRefManager {
* @param {number} [args.depth = undefined] - The maximum depth to resolve symbolic refs.
* @returns {Promise<string>} - The resolved object ID.
*/
- static async resolve({ fs, gitdir, ref, depth = undefined }) {
+ static async resolve({
+ fs,
+ gitdir,
+ ref,
+ depth = undefined,
+ visited = new Set(),
+ }) {
if (depth !== undefined) {
depth--
if (depth === -1) {
@@ -266,7 +273,7 @@ export class GitRefManager {
// Is it a ref pointer?
if (ref.startsWith('ref: ')) {
ref = ref.slice('ref: '.length)
- return GitRefManager.resolve({ fs, gitdir, ref, depth })
+ return GitRefManager.resolve({ fs, gitdir, ref, depth, visited })
}
// Is it a complete and valid SHA?
if (ref.length === 40 && /[0-9a-f]{40}/.test(ref)) {
@@ -285,7 +292,21 @@ export class GitRefManager {
packedMap.get(ref)
)
if (sha) {
- return GitRefManager.resolve({ fs, gitdir, ref: sha.trim(), depth })
+ // Guard against circular symbolic references (e.g. a -> b -> a). Without
+ // tracking visited refs this recursion would not terminate.
+ if (visited.has(ref)) {
+ throw new InternalError(
+ `Circular reference detected while resolving ref "${ref}"`
+ )
+ }
+ visited.add(ref)
+ return GitRefManager.resolve({
+ fs,
+ gitdir,
+ ref: sha.trim(),
+ depth,
+ visited,
+ })
}
}
Exploit Details
- GitHub Pull Request #2370 Regression Test: Official Jest regression test (tests/test-GitRefManager-symref-cycle.js) demonstrating non-terminating resolution on circular symbolic references (a -> b -> a).
Mitigation Strategies
- Upgrade isomorphic-git to version 1.38.6 or later to enable automatic cycle detection during symbolic reference resolution.
- Restrict git.clone and git.fetch operations to trusted, authenticated remote repositories over encrypted transports (HTTPS/SSH) to prevent rogue server or MitM exploitation.
- Audit and sanitize local .git/refs/remotes/ directories for mutually referential 'ref: ' pointers if a workspace becomes unresponsive or throws Circular reference InternalErrors.
- Supply an explicit numeric 'depth' parameter (such as depth: 5) whenever directly calling the internal GitRefManager.resolve() API.
Remediation Steps:
- Update package.json to require 'isomorphic-git': '^1.38.6' and run 'npm install isomorphic-git@^1.38.6' (or the equivalent yarn/pnpm command).
- Verify the installed version using 'npm list isomorphic-git' to ensure no transitive dependencies resolve to versions below 1.38.6.
- For any existing local repositories that fail to open or resolve references, check '.git/refs/remotes/' for files containing 'ref: ' that point to each other in a loop, and delete the offending files.
References
- GitHub Security Advisory GHSA-96wc-2m84-2cj7
- Fix Commit 823843d1cd19182df79bc907c767f5bcecb39a0b
- Pull Request #2370: fix: fixing git internals
- isomorphic-git Release v1.38.6
- NVD - CVE-2026-63475 Detail
- CVE.org Record: CVE-2026-63475
- CVE List V5 JSON Record for CVE-2026-63475
- Red Hat Bugzilla Bug #2566211
- Red Hat Customer Portal CVE-2026-63475
Read the full report for CVE-2026-63475 on our website for more details including interactive diagrams and full exploit analysis.
Originally published by Dev.to Security. Aggregated on AIWithGhost for educational purposes — full credit and traffic to the original publisher.