esm.sh CVE-2025-65025
CRITICALAttack ChainAIDerived
Hypothetical attack flow derived from CVE metadata – not a confirmed exploit chain
-
AccessPoint esm.sh at attacker registry via X-Npmrc
-
DeliveryServe crafted npm tarball with ../ paths
-
ExploitTrigger unvalidated path.Join in tarball extraction
-
ExecutionWrite attacker .js to arbitrary path
-
ImpactAchieve file write / potential code execution
Vulnerability Assessment
| Weakness |
CWE
OWASP Top 10:2025
A01:2025 - Broken Access Control
ASVS 5.0
V5 - File Handling Path canonicalization, traversal prevention
MITRE ATT&CK
2 techniques across 2 tactics: Discovery, Collection The technique list with ATT&CK links and the kill-chain view is part of the Basic plan and up. |
| Exploitation Conditions | Exploitation requires the attacker to control the npm registry that esm.sh fetches from: the GHSA advisory states official registries (npm, GitHub) reject tarball entries containing '../', so the attacker must set the registry to an attacker-controlled server using the X-Npmrc request header and then serve a malicious tarball with traversal paths. A further limiting factor is esm.sh's extension allow-list in extractPackageTarball() - only files with permitted extensions (.js, .css, .json, etc.) are written, so the arbitrary-write primitive is constrained to those file types (which still permits dropping executable .js into sensitive locations). No user authentication is indicated (PR:N), and affected versions are all esm.sh prior to v136. The attack needs no victim interaction but does depend on the X-Npmrc header being honored by the target instance. |
| Impact | Signals conflict sharply. The CVSS 3.1 vector (AV:N/AC:L/PR:N/UI:N, 9.8 Critical) and CWE-22 path traversal describe a remotely reachable, unauthenticated arbitrary file write, and a public PoC plus GHSA advisory (GHSA-h3mw-4f23-gwpw) confirm the technique is reproducible - publicly available exploit code exists. Against that, EPSS is only 0.05% (14th percentile) and the vulnerability is NOT in CISA KEV, indicating no observed widespread exploitation. The low EPSS is consistent with the real exploitation gatekeeper the advisory discloses: a straightforward attack requires the attacker to force esm.sh to pull a malicious tarball from an attacker-controlled registry via the X-Npmrc header, since official registries (npm, GitHub) reject paths containing '../'. This is a genuine high-priority issue for anyone running a self-hosted or public esm.sh instance below v136 - arbitrary file write with permissive network reachability is a plausible path to code execution - but the modest EPSS and absence of KEV suggest exploitation is currently opportunistic/targeted rather than mass-automated. The confidentiality impact rating (C:H) is somewhat generous for a primitive that is fundamentally a file write; impact is driven by integrity/availability and the realistic escalation to RCE, so treat C:H as inferred rather than direct. |
| Exploit ScenarioDerived | An attacker sends a request to an esm.sh instance with an X-Npmrc header pointing the package registry to an attacker-controlled server, then serves a crafted npm tarball whose entries use paths like 'package/../../../../tmp/evil.js'. When esm.sh downloads and extracts the tarball via extractPackageTarball(), path.Join normalizes the traversal and writes the attacker's .js file outside the intended node_modules directory to an arbitrary server location. A working PoC (malicious tarball generator plus Flask registry server) is published in the GHSA advisory. |
Get an e-mail when this CVE is exploited, patched or re-scored. Free account.
Alert meAnalysisAIv2 – Oct 18, 2026
Path traversal during NPM tarball extraction in esm.sh CDN versions prior to 136 allows unauthenticated remote attackers to write files outside the intended package directory. Exploitation requires the attacker to point esm.sh at an attacker-controlled registry via the X-Npmrc header, because official registries reject tarball entries containing '../'; the built-in extension allow-list limits writes to file types such as .js, .css, and .json, but still permits dropping executable JavaScript into sensitive locations. Publicly available exploit code exists, no CISA KEV confirmation of active exploitation was provided, and EPSS is low at roughly 0.05% (14th percentile); the vendor-released fix is version 136.
Earlier versions of this analysis (1)
esm.sh is a nobuild content delivery network(CDN) for modern web development. Rated high severity (CVSS 8.2), this vulnerability is remotely exploitable, no authentication required, low attack complexity. Public exploit code available.
RemediationAI
Vendor-released patch: version 136. Upgrade esm.sh to 136 or later; for Go module consumers, the fixed pseudo-version is 0.0.0-20251117232647-9d77b88c3207, delivered by commit 9d77b88c320733ff6689d938d85d246a3af9af16 (https://github.com/esm-dev/esm.sh/commit/9d77b88c320733ff6689d938d85d246a3af9af16). If immediate upgrade is not possible, restrict or disable client control of the X-Npmrc header so that only trusted registries can be used, with the trade-off that users lose the ability to fetch from arbitrary private or alternative registries. Additionally, run tarball extraction in a sandboxed or containerized worker with a read-only filesystem outside its scratch directory and restrict egress from the esm.sh service to approved registry hosts; these controls reduce the impact of a successful traversal but do not fix the underlying path-validation flaw. Review the vendor advisory GHSA-h3mw-4f23-gwpw for further details and monitor filesystem writes outside expected package directories for indicators of attempted exploitation.
Affected Packages
Source: OSV (Open Source Vulnerabilities)
Affects your stack
Affects 1 package in go
Checking this CVE against your own stacks and servers is part of the Basic plan and up.
Technical ContextAI · show details
esm.sh is a no-build CDN for modern web development that downloads and extracts NPM package tarballs on the server. The vulnerable code is extractPackageTarball in server/npmrc.go: after stripping the tarball's root directory, it computes filename := path.Join(pkgDir, name) without validating that the resulting path remains inside pkgDir. Because path.Join normalizes '..' segments, an entry such as package/../../tmp/evil.js resolves outside the package extraction directory, a classic tar-slip variant of CWE-22 path traversal. The advisory notes that npm and GitHub registries reject tarball entries containing '../', but the X-Npmrc request header lets a caller specify an arbitrary registry; an attacker can therefore serve a malicious tarball from their own registry and trigger the traversal. The extension allow-list in the extraction routine restricts which files are written (.js, .css, .json, and similar), constraining the primitive to those file types while still allowing executable JavaScript to be placed in sensitive locations. The upstream fix commit 9d77b88c320733ff6689d938d85d246a3af9af16 changes the extraction path handling to clean the entry name before joining it to the package directory.
Know when Esm Sh gets its next vulnerability
- Watch products and get an email when something new is published
- Check this CVE against your own stack and servers
- Exploit and PoC references, threat intelligence from 22 sources
No credit card · 7-day full trial
Severity by source
AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H
Remote, unauthenticated via X-Npmrc header (AV:N/PR:N/AC:L); primitive is arbitrary file write so I:H/A:H, but confidentiality is only indirect (C:L) absent a direct read.
AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:H/A:N
Primary rating from NVD.
CVSS VectorNVD
Lifecycle Timeline
6DescriptionNVD
esm.sh is a nobuild content delivery network(CDN) for modern web development. Prior to version 136, the esm.sh CDN service is vulnerable to path traversal during NPM package tarball extraction. An attacker can craft a malicious NPM package containing specially crafted file paths (e.g., package/../../tmp/evil.js). When esm.sh downloads and extracts this package, files may be written to arbitrary locations on the server, escaping the intended extraction directory. This issue has been patched in version 136.
Executive ViewAI
A critical path traversal flaw in esm.sh CDN releases prior to version 136 allows unauthenticated attackers to write files outside intended package directories, potentially placing executable JavaScript in sensitive locations on affected systems. Any team running an unpatched esm.sh instance - particularly one exposed to untrusted traffic or configured to fetch from external registries - should be treated as at risk, since successful exploitation could undermine the integrity of assets served to downstream applications and users.
Apply vendor patch. Until version 136 is deployed, block or strip the X-Npmrc header at the reverse proxy or WAF, restrict esm.sh to official registries only, and monitor for suspicious file writes outside intended package directories.
Threat Intelligence Overview
How this decision was reached
The engine reads each signal below and applies a fixed list of rules from top to bottom. The first rule that matches sets the recommended action – like a statement, every line is shown.
What every action level means
SSVC AssessmentENISA
Priority Score
Attack Technique
Path traversal exploits occur when applications use user-controlled input to construct file system paths without proper validation.
Affected Products (CPE)NVD
Template literal injection in esm.sh before version 136 allows unauthenticated remote attackers to execute arbitrary Jav
Path traversal in esm.sh CDN prior to version 0.0.0-20260116051925-c62ab83c589e allows unauthenticated remote attackers
esm.sh is a no-build content delivery network (CDN) for web development. In version 136, esm.sh is vulnerable to a full-
esm.sh versions up to 137 contain an SSRF vulnerability in the `/http(s)` fetch route that allows remote attackers to by
NVD
CVE.org
EPSS
GitHub
Exploit-DB