GHSA-cw2g-2vwq-88w6

Suggest an improvement
Source
https://github.com/advisories/GHSA-cw2g-2vwq-88w6
Import Source
https://github.com/github/advisory-database/blob/main/advisories/github-reviewed/2026/11/GHSA-cw2g-2vwq-88w6/GHSA-cw2g-2vwq-88w6.json
JSON Data
https://api.osv.dev/v1/vulns/GHSA-cw2g-2vwq-88w6
Aliases
Published
2026-11-09T20:13:52Z
Modified
2026-11-09T20:30:04Z
Severity
  • 5.3 (Medium) CVSS_V3 - CVSS:3.1/AV:N/AC:H/PR:N/UI:R/S:U/C:N/I:H/A:N CVSS Calculator
Summary
isomorphic-git: Path traversal via a ".." tree-entry name writes files outside the working directory on clone/checkout
Details

Summary

isomorphic-git's tree parser (src/models/GitTree.js) validates each entry name only against the path separators / and \. It does not reject the standalone reserved name .., so a malicious repository can, on a single clone/checkout, write files outside the working directory (unbounded depth). Works on any host-backed fs provider.

Details

The guard is:

// src/models/GitTree.js
if (path.includes('\\') || path.includes('/')) {
  throw new UnsafeFilepathError(path)
}

The standalone string .. passes. isomorphic-git assembles the full path incrementally across tree levels, so nesting .. trees yields ../escaped.txt, ../../escaped.txt, … with unbounded depth (each level is a separate tree object that passes the per-entry guard). On checkout mkdir(workdir/..) hits EEXIST (ignored) and the file is written above the working directory. Depth is chosen to reach the home dir, /etc, /tmp, etc.; overwriting a shell rc / config / startup file can escalate to code execution.

Canonical git behavior (divergence)

git rejects this via verify_path(): git read-tree fails with error: invalid path '../escaped.txt' and git fsck flags warning … hasDotdot: contains '..'. (git's verify_path also rejects . and .git, the latter flagged by fsck as hasDotgit — see the fix note below.) GitHub runs fsck on push, so such a tree can't be hosted there; reach is limited to a self-hosted/Smart-HTTP remote or a MitM.

PoC

https://github.com/spiceoverflow/av2-dotdot-traversal — open in a Codespace; a single git.clone() from the bundled server writes escaped.txt one directory above the clone target (DEPTH=N escapes N levels):

[AV-2] *** PATH TRAVERSAL CONFIRMED ***
[AV-2] File written outside workdir: …/escaped.txt

Impact

A path-traversal arbitrary file write outside the working directory (CWE-22), triggered by a single clone/checkout; it can escalate to code execution by overwriting shell rc, config, or startup files.

Any application or user that clones/checks out an untrusted (or compromised / MitM'd) repository with isomorphic-git on a host-backed filesystem (Linux, macOS, or Windows — no symlink or privilege required). Requires a non-GitHub remote (self-hosted / Smart-HTTP) or a MitM, since GitHub's fsck rejects trees containing ...

Suggested fix

In the tree parser, reject any entry name equal to . or ... For full verify_path parity it should also reject .git (case-insensitively, trailing dots/spaces stripped) and the NTFS 8.3 / HFS variants git blocks. Note: a literal .git entry is not independently exploitable via clone/checkout in current isomorphic-git — the checkout walk skips a .git tree entry (a sibling file is written but the .git entry is not), so rejecting .git is defense-in-depth / git parity rather than a separately demonstrated bug. Additionally, normalize and bounds-check the assembled full path against the working-tree root before any filesystem write.

Database specific
{
    "cwe_ids": [
        "CWE-22"
    ],
    "github_reviewed": true,
    "github_reviewed_at": "2026-11-09T20:13:52Z",
    "nvd_published_at": "2026-11-03T20:18:16Z",
    "severity": "MODERATE"
}
References

Affected packages

npm / isomorphic-git

Package

Name
isomorphic-git
View open source insights on deps.dev
Purl
pkg:npm/isomorphic-git

Affected ranges

Type
SEMVER
Events
Introduced
0 Unknown introduced version / All previous versions are affected
Fixed
1.38.6

Database specific

last_known_affected_version_range
"<= 1.38.5"
source
"https://github.com/github/advisory-database/blob/main/advisories/github-reviewed/2026/11/GHSA-cw2g-2vwq-88w6/GHSA-cw2g-2vwq-88w6.json"