CVEReports
CVEReports

Automated vulnerability intelligence platform. Comprehensive reports for high-severity CVEs generated by AI.

Product

  • Home
  • Sitemap
  • RSS Feed

Company

  • About
  • Contact
  • Privacy Policy
  • Terms of Service

© 2026 CVEReports. All rights reserved.

Made with love by Amit Schendel & Alon Barad



CVE-2026-23644

TarSlip on the CDN: Breaking esm.sh with Path Traversal

Alon Barad
Alon Barad
Software Engineer

Feb 16, 2026·6 min read·24 visits

Executive Summary (TL;DR)

esm.sh failed to properly sanitize file paths inside NPM tarballs. Attackers can upload a package containing filenames like `../../evil.js`, causing the server to write files outside the intended directory. This can poison the CDN cache or overwrite server configs.

A critical Path Traversal vulnerability (TarSlip) in the esm.sh CDN allows attackers to escape the extraction directory when processing NPM packages. By crafting a malicious tarball with relative path sequences, an attacker can overwrite arbitrary files on the server, leading to potential Remote Code Execution (RCE) via cache poisoning or configuration tampering.

The Hook: When CDNs Go Rogue

We all love esm.sh. It’s the magic wand of the modern web—no build steps, just import and go. It acts as a bridge between the chaotic world of NPM and the browser, fetching packages, transpiling them, and serving them up on a silver platter. But here's the thing about magic: it usually relies on a lot of complex plumbing behind the scenes. And in this case, the plumbing involved untrusted tarballs.

At its core, esm.sh is a glorified unzipper. It grabs a compressed file from a registry (like NPM), extracts it to a temporary directory, and processes the contents. This is a classic setup for one of the oldest tricks in the book: the TarSlip attack. If you blindly trust the filenames inside a tar archive, you're asking for trouble. It's the digital equivalent of letting a delivery driver walk into your house and place a package directly into your safe, simply because the label said "To: Safe".

CVE-2026-23644 isn't just a file write bug; it's a potential supply chain nuke. Since esm.sh caches these files to serve to millions of users, poisoning the cache means poisoning every developer and application downstream that relies on that specific package version.

The Flaw: Trusting the Path

The vulnerability lies in the extractPackageTarball function. The developers made a classic mistake: confusing lexical cleaning with security boundaries. In Go, path.Clean (note the missing file prefix) is designed for URL-like paths. It simplifies strings like a/b/../c into a/c. It does not, however, check if the resulting path actually stays inside a specific directory on the host's filesystem.

Here is the logic flaw in a nutshell: The code attempted to split the filename by the first slash to remove the root folder (usually package/), and then joined it with the destination directory. But what happens if the tar entry is named package/../../../../etc/passwd? The split removes package/, leaving ../../../../etc/passwd. path.Join then happily concatenates this to your pkgDir.

Because the code wasn't verifying the final resolved path against the intended root directory, the operating system (or the filepath package if it were used correctly) would interpret those .. sequences effectively, walking right out of the sandbox. The developer locked the front door but left the walls completely missing.

The Code: Autopsy of a TarSlip

Let’s look at the vulnerable code pattern found in commit 9d77b88. It uses path (generic) instead of filepath (OS-aware) and relies on weak string manipulation.

The Vulnerable Code:

// Danger: blindly joining paths
_, name := utils.SplitByFirstByte(h.Name, '/')
// path.Clean purely parses the string, it doesn't resolve OS paths
filename := path.Join(pkgDir, path.Clean(name))
 
file, err := os.Create(filename) // OOPS. We just wrote outside pkgDir.

The Fix (Commit c62ab83c589e7b421a0e1376d2a00a4e48161093):

The patch introduces a robust defense-in-depth strategy. They switched to filepath, implemented a strict normalizer, and crucially, added an allowlist for extensions.

// 1. Normalize and strip leading slashes/dots
name := utils.NormalizePathname(h.Name)[1:]
 
// 2. Strict Extension Allowlist (Whitelisting > Blacklisting)
// Only allow web-safe assets (.js, .css, .json, etc.)
if !assetExts[ext] && !moduleExts[ext] {
    continue
}
 
// 3. Prevent symbolic link attacks
if h.Typeflag != tar.TypeReg {
    continue
}
 
// 4. Secure Join
targetPath := filepath.Join(pkgDir, name)
// (Implicit check: NormalizePathname prevents '..' traversal)

This fix is aggressive. By rejecting anything that isn't a regular file (no symlinks!) and enforcing strict extensions, they killed an entire class of attacks, not just the path traversal.

The Exploit: Poisoning the Well

Exploiting this requires a bit of creativity because we want to achieve something meaningful, not just write a junk file. Since esm.sh is a CDN, our goal is Cache Poisoning.

Attack Scenario:

  1. Preparation: We create a malicious NPM package evil-lib. Inside, we craft a tarball manually. We don't use npm pack; we use a script to insert a file header with the name package/../../installed_pkg/index.js.
  2. Targeting: We target a popular library that is likely already cached on the server, or we aim to overwrite a configuration file if we know the server layout.
  3. The Trigger: We publish evil-lib to the NPM registry (or a proxy). Then, we curl https://esm.sh/evil-lib. The server pulls our tarball and triggers the extraction logic.
  4. The Payload: The server extracts our file. The ../ sequences traverse out of the temp directory for evil-lib and overwrite the index.js of react or lodash stored in the adjacent directory.

Now, anyone requesting react from esm.sh gets our backdoor. This is supply chain poisoning at the infrastructure level.

The Impact: Why You Should Care

The CVSS score of 7.7 is respectable, but the business impact is catastrophic. For a service like esm.sh, integrity is the product. If users cannot trust that the code served matches the code published on NPM, the service is dead.

Potential Consequences:

  • RCE via Configuration: If the attacker can overwrite a .env file or a server config file (e.g., config.json), they can point the database credentials to their own server or change execution flags.
  • Mass Distribution of Malware: As described in the exploit section, overwriting widely used JavaScript libraries allows the attacker to inject crypto-miners, keyloggers, or session stealers into thousands of websites instantly.
  • Denial of Service: Simply overwriting critical system binaries or filling the disk with garbage data outside the temp folder.

The Fix: Remediation & Lessons

If you are running a self-hosted instance of esm.sh, you need to update immediately. The vulnerability was patched in commit c62ab83c589e7b421a0e1376d2a00a4e48161093 (Jan 16, 2026).

For Developers (The Golden Rule of Archives):

Never, ever trust the file paths inside a zip, tar, or any archive format. They are user input. Treat them with the same hostility you treat SQL parameters.

  1. Resolve Absolute Paths: Calculate filepath.Abs(destination_dir).
  2. Join and Check: Join the user-provided path with the destination. Calculate the absolute path of the result.
  3. Verify Prefix: Ensure the result starts with the intended destination directory prefix.
// The Safe Way
dest := "/tmp/safe_zone"
pathInArchive := header.Name // e.g., "../../etc/passwd"
 
// Join them
fullPath := filepath.Join(dest, pathInArchive)
 
// Check if it starts with dest
if !strings.HasPrefix(fullPath, filepath.Clean(dest) + string(os.PathSeparator)) {
    panic("Hacker detected!")
}

Official Patches

esm-devOfficial patch commit on GitHub

Fix Analysis (1)

Technical Appendix

CVSS Score
7.7/ 10
CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:H/VI:N/VA:N/SC:N/SI:N/SA:N/E:P
EPSS Probability
0.06%
Top 81% most exploited

Affected Systems

esm.sh (Self-hosted instances)Go applications using insecure tar extraction patterns

Affected Versions Detail

Product
Affected Versions
Fixed Version
esm.sh
esm-dev
< 0.0.0-20260116051925-c62ab83c589e0.0.0-20260116051925-c62ab83c589e
AttributeDetail
CWE IDCWE-22 (Improper Limitation of a Pathname to a Restricted Directory)
Attack VectorNetwork
CVSS v4.07.7 (High)
EPSS Score0.00061 (Low Probability)
ImpactArbitrary File Write / RCE
Exploit StatusPoC Available (TarSlip Standard)

MITRE ATT&CK Mapping

T1083File and Directory Discovery
Discovery
T1190Exploit Public-Facing Application
Initial Access
CWE-22
Improper Limitation of a Pathname to a Restricted Directory ('Path Traversal')

The software uses external input to construct a pathname that is intended to identify a file or directory that is located underneath a restricted parent directory, but the software does not properly neutralize special elements within the pathname that can cause the pathname to resolve to a location that is outside of the restricted directory.

Known Exploits & Detection

GitHub Security AdvisoryAdvisory detailing the TarSlip vulnerability and path traversal vectors.
NucleiDetection Template Available

Vulnerability Timeline

Incomplete fix (9d77b88) committed
2025-11-17
Robust fix (c62ab83) committed
2026-01-16
CVE-2026-23644 assigned
2026-01-18
Added to CISA KEV
2026-01-20

References & Sources

  • [1]GHSA-2657-3c98-63jq Advisory
  • [2]Snyk: Zip Slip Vulnerability Research

Attack Flow Diagram

Press enter or space to select a node. You can then use the arrow keys to move the node around. Press delete to remove it and escape to cancel.
Press enter or space to select an edge. You can then press delete to remove it or escape to cancel.

More Reports

•11 minutes ago•GHSA-J8V8-G9CX-5QF4
8.8

GHSA-J8V8-G9CX-5QF4: Missing Authorization and Access Control Flaw in @better-auth/scim

An authorization bypass vulnerability in the @better-auth/scim plugin allows authenticated attackers to hijack personal SCIM providers and subsequently perform full account takeovers.

Alon Barad
Alon Barad
2 views•6 min read
•about 1 hour ago•GHSA-FQF6-GXHH-2XHW
6.6

GHSA-FQF6-GXHH-2XHW: Silent Data Loss and Behavioral Mismatch in uutils coreutils Backup Logic

A behavioral mismatch vulnerability (CWE-701) in the Rust-based uutils coreutils implementation of common command-line utilities allows silent data loss. When the --suffix argument is executed without explicit backup flags, the uucore library fails to enter backup mode, silently overwriting target files instead of creating preserving copies as expected under GNU standards.

Amit Schendel
Amit Schendel
4 views•7 min read
•about 2 hours ago•CVE-2025-46571
5.4

CVE-2025-46571: Stored Cross-Site Scripting (XSS) in Open WebUI

Open WebUI versions prior to 0.6.6 contain a stored cross-site scripting (XSS) vulnerability that allows low-privileged users to upload malicious HTML files containing arbitrary JavaScript. When viewed by an administrator, the executed script can abuse administrative APIs to register malicious functions, leading to remote code execution on the underlying server host.

Amit Schendel
Amit Schendel
4 views•6 min read
•about 3 hours ago•CVE-2025-46719
7.4

CVE-2025-46719: Stored XSS and Administrative RCE in Open WebUI

A critical Stored Cross-Site Scripting (XSS) vulnerability exists in Open WebUI versions prior to 0.6.6. The vulnerability resides in client-side Markdown rendering, where unvalidated iframe tags containing local API base URLs bypass DOMPurify sanitization. This flaw allows authenticated attackers to steal user session tokens. If an administrative session is compromised, the attacker can leverage the application's native Python execution capabilities ('Functions') to achieve arbitrary Remote Code Execution (RCE) on the hosting server.

Alon Barad
Alon Barad
4 views•6 min read
•about 3 hours ago•CVE-2026-26192
7.3

CVE-2026-26192: Stored Cross-Site Scripting via Insecure Iframe Sandbox in Open WebUI

CVE-2026-26192 is a high-severity Stored Cross-Site Scripting (XSS) vulnerability in Open WebUI prior to version 0.7.0. Authenticated users can modify chat history metadata to force document citations to render inside an HTML iframe configured with an insecure sandbox policy. By combining 'allow-scripts' and 'allow-same-origin', the sandbox boundary is neutralized. This allows scripts executing within the iframe to access the parent window's DOM, extract sensitive Web UI local storage keys (such as authentication JWTs), and perform state-changing actions on behalf of other users, including administrators.

Amit Schendel
Amit Schendel
5 views•6 min read
•about 4 hours ago•CVE-2026-26193
7.3

CVE-2026-26193: Stored XSS via iFrame Embeds in Open WebUI Response Messages

CVE-2026-26193 is a stored Cross-Site Scripting (XSS) vulnerability in Open WebUI prior to version 0.6.44. The vulnerability arises because the rendering engine hardcodes insecure sandbox options on an iframe component used for response embeds, allowing attackers to execute JavaScript in the parent window origin.

Amit Schendel
Amit Schendel
4 views•7 min read