NIST deprecates RSA-2048 from 2030. Find every one of them before attackers do.
📦
📦 npm
Not in CISA KEV
MEDIUM severity

isomorphic-git: Circular symbolic references cause non-terminating resolution (DoS)GHSA-96wc-2m84-2cj7

MEDIUMFix: isomorphic-git/isomorphic-git#2370

GHSA-96wc-2m84-2cj7 is a medium-severity (CVSS 4.3) CWE-674 vulnerability in isomorphic-git. A fix is available for isomorphic-git — see the affected versions and patch details below.

Also known asCVE-2026-63475
Published
Updated
Affected
1 pkg
Patched
1 / 1
Exploits
None indexed
Exploitation data as of Nov 9, 2026 · OSV.dev, NVD, FIRST.org (EPSS)

EPSS Exploitation Probability

via FIRST.org ↗
0.4%probability of exploitation in next 30 days
Lower Risk0.00%
Lower risk than most CVEs34th percentile — riskier than 34% of all scored CVEsHighest risk

Probability of exploitation in the next 30 days, from FIRST.org EPSS.

How urgent is this, really

Where this sits among everything scored

Real-World Exposure

1 pkg affected
📦isomorphic-git

Real-time download stats are indexed for npm and PyPI packages. This vulnerability affects npm packages — download data is not available via public APIs for these ecosystems.

Description

Summary

A malicious server can advertise circular symref= capabilities (e.g. a → b and b → a). isomorphic-git writes them to disk as loose symrefs, and GitRefManager.resolve() follows them with no depth limit and no cycle detection, so any later operation that resolves one of them (log, status, checkout, branch, …) loops forever — a persistent denial of service from a single clone.

Details

src/managers/GitRefManager.js — resolve() only enforces a depth limit when a depth argument is passed (depth = undefined by default), and has no visited-set:

static async resolve({ fs, gitdir, ref, depth = undefined }) {
  if (depth !== undefined) { depth--; if (depth === -1) return ref }
  …
}

updateRemoteRefs persists all server-supplied symrefs unconditionally. After clone the client has refs/remotes/origin/a → ref: refs/remotes/origin/b and b → a on disk; resolving either never terminates. Because the bad refs live on disk, the repo is effectively bricked for the application.

Canonical git behavior (divergence)

git caps symref resolution at SYMREF_MAXDEPTH = 5 (refs.c): git rev-parse a returns immediately with warning: ignoring dangling symref — no recursion, no hang.

PoC

https://github.com/spiceoverflow/av5-circular-symref — open in a Codespace; clone writes the circular symrefs, then git.log on one never returns (the runner stops it after a 20s hang):

[AV-5] refs/remotes/origin/a contains: ref: refs/remotes/origin/b
[AV-5] refs/remotes/origin/b contains: ref: refs/remotes/origin/a
[run] *** DoS CONFIRMED: resolving a circular symref never terminates ***

Impact

A persistent denial of service via non-terminating symbolic-ref resolution (CWE-674 / CWE-835). After a single clone from a malicious (or MitM'd) server the circular refs are written to disk, so every later operation that resolves them (log, status, checkout, branch, …) hangs forever — the repository becomes effectively unusable for the application.

Impacted: any application that clones from untrusted/compromised remotes with isomorphic-git.

Suggested fix

Add visited-set cycle detection (and/or a default maximum depth, as git does) in GitRefManager.resolve(); optionally validate server-supplied symref targets before persisting.

Affected Packages

1 total 1 fixed
EcosystemPackageVulnerable rangeFix
📦npmisomorphic-gitall versions1.38.6npm install isomorphic-git@1.38.6

Detection & mitigation playbook

Open-source dependency
  1. Detect

    Scan your dependency tree (package-lock.json, pnpm-lock.yaml, requirements.txt, go.sum, etc.) for isomorphic-git, including transitive dependencies — a direct dependency you never call can still pull in a vulnerable version.

  2. Fix

    Update isomorphic-git to 1.38.6 or later, then make sure no transitive (indirect) dependency still pins the vulnerable range — O3 confirms GHSA-96wc-2m84-2cj7 is resolved across your whole dependency graph.

  3. Workarounds

    Stop feeding it untrusted input: reject or quarantine files and payloads from unverified sources until you can upgrade, restrict accepted formats to the ones you actually need, and run the parsing or decoding step in a least-privileged sandbox or short-lived worker so a crash or corrupted read cannot reach the rest of the process.

Frequently Asked Questions

### Summary A malicious server can advertise circular `symref=` capabilities (e.g. `a → b` and `b → a`). isomorphic-git writes them to disk as loose symrefs, and `GitRefManager.resolve()` follows them with no depth limit and no cycle detection, so any later operation that resolves one of them (`log`, `status`, `checkout`, `branch`, …) **loops forever** — a persistent denial of service from a single clone. ### Details `src/managers/GitRefManager.js` — `resolve()` only enforces a depth limit when a `depth` argument is passed (`depth = undefined` by default), and has no visited-set: ```js stati
O3 Security · Impact-Aware SCA

Is GHSA-96wc-2m84-2cj7 in your dependencies?

Find it across npm, including transitive dependencies.

isomorphic-git: Circular symbolic references cause…