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/celestiapackages/binaries/near-sandboxpackages/binaries/ordpackages/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.
Prevention & Best Practices
- Pin and monitor extraction library versions. Archive/extraction libraries (
decompress,tar,extract-zip,unzipper, etc.) are a recurring source of zip-slip CVEs. Treat them like any other security-sensitive dependency and keep them on active, patched release lines. - Never trust archive entry paths. If you ever write custom extraction logic, always resolve the final path with
path.resolve(destDir, entry.path)and verify it still starts withdestDir(with a trailing separator check to avoid prefix-matching bypasses likedestDir-evil) before writing. - Restrict extraction sources. Only extract archives from sources you control or that are integrity-verified (checksums/signatures) — this matters directly for the
bin-wrapper-based binary downloads inpackages/binaries/*. - Automate dependency scanning. Trivy caught this via lockfile analysis against the CVE database; running this kind of SCA scan in CI on every
bun.lock/package.jsonchange catches these before they ship. - Reference CWE-22 in your secure coding guidelines and code review checklists whenever a change touches file extraction, template rendering with file paths, or any code that joins user- or archive-supplied path segments with a base directory.
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, andsolana-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-wrapperinpackages/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-wrapperto^13.2.0(pulling in patched@xhmikosr/decompress@10.2.1/11.1.3) inpackage.jsonand regeneratedbun.lockaccordingly.
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.
References
- CWE-22: Improper Limitation of a Pathname to a Restricted Directory — https://cwe.mitre.org/data/definitions/22.html
- OWASP Path Traversal Cheat Sheet — https://owasp.org/www-community/attacks/Path_Traversal
- Node.js
pathmodule documentation (safe path resolution) — https://nodejs.org/api/path.html - Semgrep rules for zip-slip / path traversal — https://semgrep.dev/r?q=zip-slip
- fix: upgrade @xhmikosr/decompress to 10.2.1, 11.1.3 (CVE-2026-53486)