Back to Blog
critical SEVERITY6 min read

How Path Traversal happens in Node.js decompress and how to fix it

A critical zip-slip vulnerability (CVE-2026-53486) in the `@xhmikosr/decompress` package allowed crafted archives to write files outside the intended extraction directory, enabling arbitrary file read/write on the host. The fix upgrades `@xhmikosr/decompress` from 5.0.0 to 10.2.1/11.1.3 and its dependency `@xhmikosr/bin-wrapper` from ^5.0.0 to ^13.2.0, closing the path-sanitization gap in the underlying extractors.

O
By Orbis AppSec
Published August 31, 2026Reviewed August 31, 2026

Answer Summary

CVE-2026-53486 is a path traversal (zip-slip, CWE-22) vulnerability in the Node.js package `@xhmikosr/decompress` (v5.0.0), where crafted archive entries with `../` sequences or absolute paths in their filenames could escape the target extraction directory during decompression, leading to arbitrary file read/write. The fix is to upgrade the dependency to `@xhmikosr/decompress@10.2.1`/`11.1.3` (and `@xhmikosr/bin-wrapper` to `^13.2.0`), which added proper entry-path validation before writing extracted files to disk.

Vulnerability at a Glance

cweCWE-22
fixUpgrade `@xhmikosr/decompress` to `10.2.1`/`11.1.3` and `@xhmikosr/bin-wrapper` to `^13.2.0` in `package.json`/`bun.lock`
riskArbitrary file read/write outside the intended extraction directory via a crafted archive
languageJavaScript / Node.js
root cause`@xhmikosr/decompress@5.0.0` did not validate extracted entry paths for `../` traversal sequences or absolute paths before writing files
vulnerabilityPath Traversal / Zip Slip in archive extraction

Introduction

The @xhmikosr/decompress package is a common building block in Node.js tooling used to unpack .zip, .tar, .tar.gz, and other archive formats — often as part of build scripts, CLI tools, or binary download helpers. In this repository, it's pulled in transitively through @xhmikosr/bin-wrapper, which several workspace packages (packages/binaries/celestia, packages/binaries/near-sandbox, packages/binaries/ord, packages/binaries/solana-node, and others) depend on to download and extract pre-built binaries during installation or build.

The problem: version 5.0.0 of @xhmikosr/decompress, tracked in bun.lock and pinned via @xhmikosr/bin-wrapper@^5.0.0, is vulnerable to CVE-2026-53486 — a critical zip-slip vulnerability that allows a maliciously crafted archive to write (or read) files outside the directory the code intended to extract into. If any workflow in this repo extracts an archive from a source that isn't fully trusted (a downloaded binary release, a CI artifact, a third-party mirror), a single crafted archive entry could overwrite files far outside the expected output folder.

Trivy's dependency scanner flagged this exact pattern against bun.lock, and while the assessment notes it as "present in dependency tree, not confirmed reachable," that's precisely the kind of latent risk that turns into a real incident the moment a build script or binary-fetch path starts consuming an untrusted archive.

The Vulnerability Explained

Archive formats like zip and tar store a relative path for every file entry — that's how you get a directory structure back out when you extract. A well-behaved archive entry looks like:

readme.txt
bin/celestia
lib/config.json

A malicious archive entry, however, can specify a path designed to escape the extraction directory:

../../../../etc/cron.d/malicious-job
../../.ssh/authorized_keys

Older versions of extraction libraries — including @xhmikosr/decompress@5.0.0 — historically did not fully canonicalize and validate each entry's destination path before writing it to disk. Internally, code in that vintage of the extractor effectively does something equivalent to:

// Simplified representation of the vulnerable pattern
const outputPath = path.join(destDir, entry.path); // entry.path is attacker-controlled
fs.writeFileSync(outputPath, entry.data);

Because path.join(destDir, entry.path) doesn't stop entry.path from containing .. segments (or an absolute path on some platforms), the resulting outputPath can resolve to a location completely outside destDir. This is the classic "zip slip" pattern, and it's exactly the class of bug CVE-2026-53486 targets in decompress.

Attack scenario specific to this codebase: The packages/binaries/* workspaces (celestia, near-sandbox, ord, solana-node) use @xhmikosr/bin-wrapper, which under the hood downloads a binary release archive and hands it to decompress for extraction. If an attacker can influence the archive source — a compromised mirror, a man-in-the-middle on an unpinned download URL, or a poisoned upstream release — they could ship a .tar.gz where one entry's path is ../../../../home/deploy/.bashrc or ../../../etc/systemd/system/backdoor.service. On extraction, that entry gets written outside the intended packages/binaries/<name>/bin/ directory, potentially achieving arbitrary file write and, depending on what gets overwritten, code execution or persistence on the build/runtime host.

The Fix

The PR resolves this by bumping the vulnerable dependency chain in package.json and regenerating bun.lock:

Before:

       "dependencies": {
         "@effectstream/binary-checksum": "workspace:*",
-        "@xhmikosr/bin-wrapper": "^5.0.0",
+        "@xhmikosr/bin-wrapper": "^13.2.0",
       },

This change is applied consistently across every workspace that pulled in the vulnerable version:

  • packages/binaries/celestia
  • packages/binaries/near-sandbox
  • packages/binaries/ord
  • packages/binaries/solana-node

@xhmikosr/bin-wrapper@^13.2.0 itself depends on a patched @xhmikosr/decompress (upgraded to 10.2.1/11.1.3 in the lockfile), which includes proper entry-path validation before extraction — rejecting or normalizing entries that would resolve outside the destination directory. The lockfile diff also shows a related transitive bump, @sindresorhus/is from 4.6.0 to 5.6.0, pulled in as part of the dependency tree update for the newer bin-wrapper/decompress chain.

Why this is the right fix, and why it's low-risk: This is a pure dependency version bump, not a behavioral rewrite of extraction logic in this repo's own code. The vulnerable code lived entirely inside @xhmikosr/decompress, so the safest and most maintainable fix is to consume the upstream patch rather than hand-roll path sanitization around a third-party extractor. Because the change only tightens how malicious archive entries are handled — legitimate archives with well-formed relative paths extract exactly as before — normal build and install workflows are unaffected.

Key Takeaways

  • @xhmikosr/decompress@5.0.0, used transitively via @xhmikosr/bin-wrapper@^5.0.0, was vulnerable to zip-slip path traversal (CVE-2026-53486) that could enable arbitrary file read/write during archive extraction.
  • Four workspaces — celestia, near-sandbox, ord, and solana-node — pulled in the vulnerable chain through their binary-download tooling and needed the bump to @xhmikosr/bin-wrapper@^13.2.0.
  • The fix is a lockfile/manifest-only change; no application code needed to be rewritten because the flaw lived entirely in the third-party extraction library.
  • Even when a scanner marks a dependency as "not confirmed reachable," it's still worth patching promptly — archive extraction paths are exactly the kind of code that gets exercised unexpectedly (CI, install scripts, binary fetchers).
  • Treat any library that writes files based on data inside an untrusted input (archives, uploads, templates) as a high-priority target for version tracking and CVE monitoring.

How Orbis AppSec Detected This

  • Source: Archive entry filenames inside a downloaded binary release (.zip/.tar.gz) fetched by @xhmikosr/bin-wrapper in packages/binaries/{celestia,near-sandbox,ord,solana-node}.
  • Sink: Internal file-write call inside @xhmikosr/decompress@5.0.0's extraction routine, which joined the untrusted entry path with the destination directory without full containment validation.
  • Missing control: No canonicalization/containment check to ensure the resolved extraction path stayed within the intended destination directory (no ..//absolute-path rejection).
  • CWE: CWE-22 (Improper Limitation of a Pathname to a Restricted Directory / Path Traversal).
  • Fix: Upgraded @xhmikosr/bin-wrapper to ^13.2.0 (pulling in patched @xhmikosr/decompress@10.2.1/11.1.3) in package.json and regenerated bun.lock accordingly.

Orbis AppSec automatically detected this vulnerability and opened a pull request with the fix. Try Orbis AppSec on your repositories to find and fix issues like this automatically.

Conclusion

CVE-2026-53486 is a textbook zip-slip vulnerability: an archive extraction library that trusted entry paths just enough to let a crafted ../ sequence escape the intended output directory, opening the door to arbitrary file read/write. Because @xhmikosr/decompress@5.0.0 sat several major versions behind and was consumed transitively across four binary-handling workspaces, the blast radius wasn't obvious from a casual read of package.json — it took dependency-tree analysis to surface it. The fix here is simple and safe: bump @xhmikosr/bin-wrapper to ^13.2.0 and let the patched @xhmikosr/decompress (10.2.1/11.1.3) enforce proper path containment. The broader lesson is to keep archive-handling dependencies current and to treat any code path that extracts, unpacks, or writes files based on external input as security-critical by default.

Prevention and further reading

View the Security Fix

Check out the pull request that fixed this vulnerability

View PR #876

Related Articles

high

modelExporter.js Path Traversal via Unsanitized Directory Concatenation

A path traversal vulnerability in `modelExporter.js` allowed attackers to read arbitrary files by injecting traversal sequences into directory and relative path parameters. The `readSourceFile` function concatenated these unsanitized inputs directly into file URLs passed to `fetch()`. The fix introduces strict path normalization that rejects attempts to escape the intended directory.

critical

How path traversal happens in PHP virtual filesystem adapters and how to fix it

A critical path traversal flaw in `VirtualAdapter.php`'s `resolveMount()` method allowed attackers to escape mounted directory boundaries using sequences like `../../../etc/passwd`. The fix introduces `PathPolicy::normalizeRelative()` to sanitize the remaining path segment before it ever reaches the underlying storage adapter.

high

How Path Traversal Happens in TensorFlow's Data Service and How to Fix It

TensorFlow's data service dispatcher validated dataset IDs against forward-slash traversal attacks but overlooked backslash characters on non-Windows platforms, allowing attackers to escape the root directory. A targeted fix adds explicit backslash validation across all platforms, closing a high-severity path traversal vulnerability in the snapshot management system.

high

How Trust-Prefix Bypass via Path Traversal Happens in Python Copier and How to Fix It

CVE-2026-53951 is a high-severity path traversal vulnerability in Copier 9.15.0 that allowed attackers to bypass trust-prefix checks and execute tasks without user confirmation. Upgrading to Copier 9.15.2 eliminates this attack vector by properly validating file paths before task execution.

critical

How Path Traversal in basic-ftp Leads to File Overwrite Attacks and How to Fix It

CVE-2026-27699 is a critical path traversal vulnerability in basic-ftp versions before 5.3.1 that allows attackers to overwrite arbitrary files on the system by crafting malicious file paths. This vulnerability was fixed by upgrading basic-ftp and enforcing strict version constraints across dependent packages. Understanding this attack and its mitigation is essential for developers using FTP libraries in production environments.

critical

How Command Injection Vulnerabilities Happen in Python Subprocess Calls and How to Fix Them

A critical command injection vulnerability was discovered in `src/unused/server/fft.py` where external binaries like `oggenc` and `cocoa_text` were executed with file path parameters that could be manipulated by user input. Although `shell=False` was used, the lack of input validation allowed attackers to potentially trigger processing of arbitrary files or cause denial of service. This fix implements proper path validation to prevent exploitation.