GitHub Advisoryadvisory · npm

GHSA-gvwx-54wh-qm9j node-tar: Uncaught Exception DoS via NUL byte in PAX path/linkpath records

MEDIUM Published 2026-07-20 Modified 2026-07-20 Official page ↗
Aliases
CVE-2026-59875
Ecosystem
npm
Packages
tar
Severity
Moderate
CVSS vector
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:L
Weaknesses
CWE-248
Reviewed
2026-07-20

Affected packages

• npm tar: < 7.5.17 → fixed in 7.5.17

Description

Summary `node-tar` strips trailing `NUL` bytes from long-name (`L`) and long-linkpath (`K`) GNU extended headers but does not apply the same sanitization to equivalent fields delivered via PAX (`x` typeflag) extended headers. A PAX record of the form `path=visible.txt\x00hidden.txt` is parsed verbatim into `entry.path` and flows into `fs.lstat()` / `fs.open()`, which Node.js core rejects with `ERR_INVALID_ARG_VALUE`. The throw originates inside an `FSReqCallback` async chain that is not wrapped by the consumer's `await/try-catch` around `tar.x()` — it surfaces as `uncaughtException` and terminates the process. This is a remote denial-of-service primitive against any process that extracts attacker-supplied tarballs through `tar.x` / `tar.extract` / `tar.t` / `tar.Parser`, even when the consumer follows the documented `try/catch` error-handling pattern. A secondary parser-differential (CWE-436) exists because `tar(1)`, `bsdtar`, and Python `tarfile` truncate the path at the first `NUL` (yielding `visible.txt`) while node-tar retains the full string. A validator that pre-scans a tarball with one tool and extracts with the other is bypassed. --- Root cause Vulnerable sink — `src/pax.ts:157-183` PAX KV records flow through `parseKVLine`. The value half (`v`) is assigned directly to the result object with no sanitization for embedded NUL bytes: ```ts // src/pax.ts:157 const parseKVLine = (set: Record, line: string) => { const n = parseInt(line, 10) if (n !== Buffer.byteLength(line) + 1) return set line = line.slice((n + ' ').length) const kv = line.split('=') const r = kv.shift() if (!r) return set const k = r.replace(/^SCHILY\.(dev|ino|nlink)/, '$1') const v = kv.join('=') // { console.log("UNCAUGHT:", e.code, "-", e.message); process.exit(99); }); import("tar").then(async tar => { try { await tar.x({ file: "../poc.tar", cwd: "./out" }); console.log("NORMAL_RETURN"); } catch (e) { console.log("CAUGHT_BY_USER:", e.code); } });' ``` Observed output (verified 2026-06-23 against `[email protected]`) ``` UNCAUGHT: ERR_INVALID_ARG_VALUE - The argument 'path' must be a string, Uint8Array, or URL without null bytes. Received '/.../out/visible.txt\x00hidden.txt' exit: 99 ``` The exception bypasses the user's `try { await tar.x(...) } catch (e) { ... }` block and lands in the global `uncaughtException` handler. In a typical server without that handler, the process exits. --- Impact Direct: remote DoS Any service that ingests attacker-supplied tarballs via node-tar inherits a one-tarball-kills-the-process primitive. Realistic deployments where this is reachable without user interaction: • npm registry tarball ingestion and downstream mirrors • GitHub Actions cache restore (`actions/cache`, `actions/setup-*` extracting toolchains) • Container image build pipelines that unpack layer tarballs through node tooling • Backup-restore services accepting user uploads • CI artifact processors and badge generators • Static-site / Docusaurus / Next.js build runners that fetch and extract dep tarballs • Cloud functions that auto-extract uploaded archives A correctly-coded consumer that does: ```js try { await tar.x({ file: req.upload.path, cwd: tmpdir }); } catch (e) { return res.status(400).json({ error: 'bad archive' }); } ``` does not catch this throw. The Node process dies and (depending on the supervisor) the worker may take time to respawn or never respawn if it dies during boot. Secondary: parser-differential validator bypass (CWE-436) | Tool | Result for `path=visible.txt\x00hidden.txt` | |----------------------------|----------------------------------------------| | GNU tar (`tar -tvf`) | Lists `visible.txt` (truncated at NUL) | | `bsdtar -tvf` | Lists `visible.txt` (truncated at NUL) | | Python `tarfile.list()` | Lists `visible.txt\x00hidden.txt` (raw)…

Related

Alias · CVE (1)

  • CVE-2026-59875 node-tar is a tar archive manipulation library for Node.js. vulnerability

Weakness · CWE (1)

  • CWE-248 Uncaught Exception weakness

References