Every CVE Search/ Get API key

CVE-2026-59875

node-tar: Uncaught Exception DoS via NUL byte in PAX path/linkpath records

5.3 MediumFix available

node-tar is a tar archive manipulation library for Node.js. Prior to 7.5.17, node-tar does not strip NUL bytes from PAX path and linkpath records in src/pax.ts, allowing a crafted archive with values to reach fs.lstat or fs.open and terminate the process with an uncaught exception. This issue is fixed in version 7.5.17.

Attack profile

How easy it is to exploit

Attack vector
Network
Complexity
Low
Privileges needed
None
User interaction
None

What an attacker can affect

Confidentiality
None
Integrity
None
Availability
Low

Exploit likelihood

0.35%Up 0.1 points since Jul 9, 2026
90%50%10%1%

What each source reports

CVE List Score used 5.3

node-tar: Uncaught Exception DoS via NUL byte in PAX path/linkpath records

node-tar is a tar archive manipulation library for Node.js. Prior to 7.5.17, node-tar does not strip NUL bytes from PAX path and linkpath records in src/pax.ts, allowing a crafted archive with values to reach fs.lstat or fs.open and terminate the process with an uncaught exception. This issue is fixed in version 7.5.17.

Record
CVE-2026-59875
CVSS 3.1
5.3 MediumCVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:L
Weakness
CWE-248
Updated
2026-11-02
EUVDEUVD-2026-42303 5.3

node-tar is a tar archive manipulation library for Node.js. Prior to 7.5.17, node-tar does not strip NUL bytes from PAX path and linkpath records in src/pax.ts, allowing a crafted archive with values to reach fs.lstat or fs.open and terminate the process with an uncaught exception. This issue is fixed in version 7.5.17.

Record
EUVD-2026-42303
CVSS 3.1
5.3 MediumCVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:L
Updated
2026-11-02
GitHub AdvisoriesGHSA-6chw-6frg-f759 7.5

Regular Expression Denial of Service in Acorn

Affected versions of acorn are vulnerable to Regular Expression Denial of Service. A regex in the form of /[x-\ud800]/u causes the parser to enter an infinite loop. The string is not valid UTF16 which usually results in it being sanitized before reaching the parser. If an application processes untrusted input and passes it directly to acorn, attackers may leverage the vulnerability leading to Denial of Service.

Record
GHSA-6chw-6frg-f759
CVSS 3.1
7.5 HighCVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H
Weakness
CWE-400
Updated
2026-11-02
GitHub AdvisoriesGHSA-gvwx-54wh-qm9j 5.3

node-tar: Uncaught Exception DoS via NUL byte in PAX path/linkpath records

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:

// src/pax.ts:157
const parseKVLine = (set: Record<string, unknown>, 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('=')                                 // <-- NO NUL STRIP
  set[k] =
    /^([A-Z]+\.)?([mac]|birth|creation)time$/.test(k) ?
      new Date(Number(v) * 1000)
    : /^[0-9]+$/.test(v) ? +v
    : v                                                  // <-- v with NULs lands here
  return set
}

The PAX record body is length-prefixed, so the parser knows the exact byte boundary — but it never checks whether the value half between = and \n contains NUL. The result is consumed by Header / ReadEntry, where entry.path and entry.linkpath carry the embedded NUL all the way to fs.lstat().

Correctly-patched cousin sink — src/parse.ts:375-388

The equivalent code path for GNU L/K long-headers does strip NUL bytes:

// src/parse.ts:375
case 'NextFileHasLongPath':
case 'OldGnuLongPath': {
  const ex = this[EX] ?? Object.create(null)
  this[EX] = ex
  ex.path = this[META].replace(/\0.*/, '')               // <-- NUL strip applied
  break
}
case 'NextFileHasLongLinkpath': {
  const ex = this[EX] || Object.create(null)
  this[EX] = ex
  ex.linkpath = this[META].replace(/\0.*/, '')           // <-- NUL strip applied
  break
}

The parse.ts fix is the maintainer's own acknowledgement that path strings on this codepath must be NUL-stripped before reaching fs.*. The PAX path produces the identical primitive but bypasses the guard.

Downstream blast radius

entry.path and entry.linkpath are consumed in:

  • src/unpack.ts → fs.lstat, fs.open, fs.symlink, fs.link, fs.mkdir
  • src/list.ts (no crash — listing tolerates NUL in strings)
  • Any consumer of the ReadEntry event that calls path.join() / fs.* on entry.path

The crash fires inside the FSReqCallback Node-internal async machinery, outside the user's await tar.x(...) Promise rejection boundary.


Proof of Concept

Artifacts

  • poc-null-byte-crash.tar — 3072 bytes — PAX path=visible.txt\x00hidden.txt
  • poc-null-linkpath-crash.tar — 2560 bytes — PAX linkpath=target\x00garbage (symlink target sink)
  • poc1-pax-prefix.py — minimal PAX-header builder (Python 3, no deps)

Tarball generator (minimal repro — Python 3)

#!/usr/bin/env python3
"""Minimal…
Record
GHSA-gvwx-54wh-qm9j
CVSS 3.1
5.3 MediumCVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:L
Weakness
CWE-248
Updated
2026-11-02
NVD 5.3

node-tar is a tar archive manipulation library for Node.js. Prior to 7.5.17, node-tar does not strip NUL bytes from PAX path and linkpath records in src/pax.ts, allowing a crafted archive with values to reach fs.lstat or fs.open and terminate the process with an uncaught exception. This issue is fixed in version 7.5.17.

Record
CVE-2026-59875
CVSS 3.1
5.3 MediumCVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:L
Weakness
CWE-248
Updated
2026-11-02
OSV 5.3

node-tar: Uncaught Exception DoS via NUL byte in PAX path/linkpath records

node-tar is a tar archive manipulation library for Node.js. Prior to 7.5.17, node-tar does not strip NUL bytes from PAX path and linkpath records in src/pax.ts, allowing a crafted archive with values to reach fs.lstat or fs.open and terminate the process with an uncaught exception. This issue is fixed in version 7.5.17.

Record
CVE-2026-59875
CVSS 3.1
5.3 MediumCVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:L
Weakness
CWE-248
Updated
2026-11-02
Show 14 moreShow less
OSVDEBIAN-CVE-2026-59875 5.3

node-tar is a tar archive manipulation library for Node.js. Prior to 7.5.17, node-tar does not strip NUL bytes from PAX path and linkpath records in src/pax.ts, allowing a crafted archive with values to reach fs.lstat or fs.open and terminate the process with an uncaught exception. This issue is fixed in version 7.5.17.

Record
DEBIAN-CVE-2026-59875
CVSS 3.1
5.3 MediumCVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:L
Updated
2026-11-02
OSVGHSA-6chw-6frg-f759 7.5

Regular Expression Denial of Service in Acorn

Affected versions of acorn are vulnerable to Regular Expression Denial of Service. A regex in the form of /[x-\ud800]/u causes the parser to enter an infinite loop. The string is not valid UTF16 which usually results in it being sanitized before reaching the parser. If an application processes untrusted input and passes it directly to acorn, attackers may leverage the vulnerability leading to Denial of Service.

Record
GHSA-6chw-6frg-f759
CVSS 3.1
7.5 HighCVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H
Weakness
CWE-400
Updated
2026-11-02
OSVGHSA-gvwx-54wh-qm9j 5.3

node-tar: Uncaught Exception DoS via NUL byte in PAX path/linkpath records

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:

// src/pax.ts:157
const parseKVLine = (set: Record<string, unknown>, 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('=')                                 // <-- NO NUL STRIP
  set[k] =
    /^([A-Z]+\.)?([mac]|birth|creation)time$/.test(k) ?
      new Date(Number(v) * 1000)
    : /^[0-9]+$/.test(v) ? +v
    : v                                                  // <-- v with NULs lands here
  return set
}

The PAX record body is length-prefixed, so the parser knows the exact byte boundary — but it never checks whether the value half between = and \n contains NUL. The result is consumed by Header / ReadEntry, where entry.path and entry.linkpath carry the embedded NUL all the way to fs.lstat().

Correctly-patched cousin sink — src/parse.ts:375-388

The equivalent code path for GNU L/K long-headers does strip NUL bytes:

// src/parse.ts:375
case 'NextFileHasLongPath':
case 'OldGnuLongPath': {
  const ex = this[EX] ?? Object.create(null)
  this[EX] = ex
  ex.path = this[META].replace(/\0.*/, '')               // <-- NUL strip applied
  break
}
case 'NextFileHasLongLinkpath': {
  const ex = this[EX] || Object.create(null)
  this[EX] = ex
  ex.linkpath = this[META].replace(/\0.*/, '')           // <-- NUL strip applied
  break
}

The parse.ts fix is the maintainer's own acknowledgement that path strings on this codepath must be NUL-stripped before reaching fs.*. The PAX path produces the identical primitive but bypasses the guard.

Downstream blast radius

entry.path and entry.linkpath are consumed in:

  • src/unpack.ts → fs.lstat, fs.open, fs.symlink, fs.link, fs.mkdir
  • src/list.ts (no crash — listing tolerates NUL in strings)
  • Any consumer of the ReadEntry event that calls path.join() / fs.* on entry.path

The crash fires inside the FSReqCallback Node-internal async machinery, outside the user's await tar.x(...) Promise rejection boundary.


Proof of Concept

Artifacts

  • poc-null-byte-crash.tar — 3072 bytes — PAX path=visible.txt\x00hidden.txt
  • poc-null-linkpath-crash.tar — 2560 bytes — PAX linkpath=target\x00garbage (symlink target sink)
  • poc1-pax-prefix.py — minimal PAX-header builder (Python 3, no deps)

Tarball generator (minimal repro — Python 3)

#!/usr/bin/env python3
"""Minimal…
Record
GHSA-gvwx-54wh-qm9j
CVSS 3.1
5.3 MediumCVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:L
Weakness
CWE-248
Updated
2026-11-02
OSVUBUNTU-CVE-2026-59875 5.3

node-tar is a tar archive manipulation library for Node.js. Prior to 7.5.17, node-tar does not strip NUL bytes from PAX path and linkpath records in src/pax.ts, allowing a crafted archive with values to reach fs.lstat or fs.open and terminate the process with an uncaught exception. This issue is fixed in version 7.5.17.

Record
UBUNTU-CVE-2026-59875
CVSS 3.1
5.3 MediumCVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:L
Updated
2026-11-02
OSVCLSA-2026-1780620684 No score

TuxCare security update for acorn (1 CVE)

TuxCare rebuilt acorn to address 1 CVE. Fixed in 6.0.4-tuxcare.1.

Record
CLSA-2026-1780620684
Updated
2026-11-02
OSVCLSA-2026-1780620685 No score

TuxCare security update for acorn (1 CVE)

TuxCare rebuilt acorn to address 1 CVE. Fixed in 6.2.0-tuxcare.1.

Record
CLSA-2026-1780620685
Updated
2026-11-02
OSVCLSA-2026-1784596283 No score

TuxCare security update for tar (4 CVEs)

TuxCare rebuilt tar to address 4 CVEs. Fixed in 6.2.1-tuxcare.4.

Record
CLSA-2026-1784596283
Updated
2026-11-02
OSVCLSA-2026-1787823889 No score

TuxCare security update for tar (6 CVEs)

TuxCare rebuilt tar to address 6 CVEs. Fixed in 6.2.0-tuxcare.1.

Record
CLSA-2026-1787823889
Updated
2026-11-02
OSVCLSA-2026-1792074268 No score

TuxCare security update for tar (8 CVEs)

TuxCare rebuilt tar to address 8 CVEs. Fixed in 6.2.0-tuxcare.5.

Record
CLSA-2026-1792074268
Updated
2026-11-02
OSVCLSA-2026-1792074305 No score

TuxCare security update for tar (12 CVEs)

TuxCare rebuilt tar to address 12 CVEs. Fixed in 6.0.2-tuxcare.6.

Record
CLSA-2026-1792074305
Updated
2026-11-02
OSVCLSA-2026-1793101936 No score

TuxCare security update for tar (6 CVEs)

TuxCare rebuilt tar to address 6 CVEs. Fixed in 6.1.0-tuxcare.3.

Record
CLSA-2026-1793101936
Updated
2026-11-02
OSVCLSA-2026-1793102032 No score

TuxCare security update for tar (5 CVEs)

TuxCare rebuilt tar to address 5 CVEs. Fixed in 6.1.6-tuxcare.2.

Record
CLSA-2026-1793102032
Updated
2026-11-02
OSVCLSA-2026-1793307830 No score

TuxCare security update for tar (11 CVEs)

TuxCare rebuilt tar to address 11 CVEs. Fixed in 4.4.19-tuxcare.5.

Record
CLSA-2026-1793307830
Updated
2026-11-02
OSVROOT-APP-NPM-CVE-2026-59875 No score

CVE-2026-59875 in tar - Patched by Root

Root has patched CVE-2026-59875 in the tar package for Root:npm. Multiple fixed versions available.

Record
ROOT-APP-NPM-CVE-2026-59875
Updated
2026-11-02

Affected products

Affected packages

Affected packages
PackageAffectedFixed
acorn
npm
6.0.0 up to 6.4.1
6.4.1
acorn
npm
7.0.0 up to 7.1.1
7.1.1
acorn
npm
5.5.0 up to 5.7.4
5.7.4
tar
npm
through 7.5.16
7.5.17
acorn
TuxCare:npm
6.0.4-tuxcare.0 up to 6.0.4-tuxcare.1, plus listed versions
6.0.4
6.0.4-tuxcare.1
acorn
TuxCare:npm
6.2.0-tuxcare.0 up to 6.2.0-tuxcare.1, plus listed versions
6.2.0
6.2.0-tuxcare.1
tar
TuxCare:npm
From an advisory covering 4 CVEs
6.2.1-tuxcare.0 up to 6.2.1-tuxcare.4, plus listed versions
6.2.16.2.1-tuxcare.16.2.1-tuxcare.26.2.1-tuxcare.3
6.2.1-tuxcare.4
tar
TuxCare:npm
From an advisory covering 7 CVEs
6.2.0-tuxcare.0 up to 6.2.0-tuxcare.5, plus listed versions
6.2.06.2.0-tuxcare.16.2.0-tuxcare.26.2.0-tuxcare.36.2.0-tuxcare.4
6.2.0-tuxcare.5
tar
TuxCare:npm
From an advisory covering 11 CVEs
6.0.2-tuxcare.0 up to 6.0.2-tuxcare.6, plus listed versions
6.0.26.0.2-tuxcare.16.0.2-tuxcare.26.0.2-tuxcare.36.0.2-tuxcare.46.0.2-tuxcare.5
6.0.2-tuxcare.6
tar
TuxCare:npm
From an advisory covering 6 CVEs
6.1.0-tuxcare.0 up to 6.1.0-tuxcare.3, plus listed versions
6.1.06.1.0-tuxcare.16.1.0-tuxcare.2
6.1.0-tuxcare.3
Show 17 moreShow less
Affected packages
PackageAffectedFixed
tar
TuxCare:npm
From an advisory covering 5 CVEs
6.1.6-tuxcare.0 up to 6.1.6-tuxcare.2, plus listed versions
6.1.66.1.6-tuxcare.1
6.1.6-tuxcare.2
tar
TuxCare:npm
From an advisory covering 10 CVEs
4.4.19-tuxcare.0 up to 4.4.19-tuxcare.5, plus listed versions
4.4.194.4.19-tuxcare.14.4.19-tuxcare.24.4.19-tuxcare.34.4.19-tuxcare.4
4.4.19-tuxcare.5
node-tar
Debian:12
All versions, plus listed versions
6.1.13+~cs7.0.5-16.1.13+~cs7.0.5-1+deb12u16.1.13+~cs7.0.5-26.1.13+~cs7.0.5-36.1.13+~cs7.0.5-4
Show 17 moreShow less
6.2.1+ds1+~cs6.1.13-16.2.1+ds1+~cs6.1.13-106.2.1+ds1+~cs6.1.13-116.2.1+ds1+~cs6.1.13-26.2.1+ds1+~cs6.1.13-36.2.1+ds1+~cs6.1.13-46.2.1+ds1+~cs6.1.13-56.2.1+ds1+~cs6.1.13-66.2.1+ds1+~cs6.1.13-76.2.1+ds1+~cs6.1.13-86.2.1+ds1+~cs6.1.13-96.2.1+~cs7.0.8-17.5.16+~4.0.1-17.5.16+~4.0.1-27.5.19+~4.0.1-17.5.19+~4.0.1-27.5.22+~4.0.1-1
None known
node-tar
Debian:13
All versions, plus listed versions
6.2.1+ds1+~cs6.1.13-16.2.1+ds1+~cs6.1.13-106.2.1+ds1+~cs6.1.13-116.2.1+ds1+~cs6.1.13-26.2.1+ds1+~cs6.1.13-3
Show 13 moreShow less
6.2.1+ds1+~cs6.1.13-46.2.1+ds1+~cs6.1.13-56.2.1+ds1+~cs6.1.13-66.2.1+ds1+~cs6.1.13-76.2.1+ds1+~cs6.1.13-86.2.1+ds1+~cs6.1.13-96.2.1+~cs7.0.8-16.2.1+~cs7.0.8-1+deb13u17.5.16+~4.0.1-17.5.16+~4.0.1-27.5.19+~4.0.1-17.5.19+~4.0.1-27.5.22+~4.0.1-1
None known
node-tar
Debian:14
before 7.5.19+~4.0.1-1, plus listed versions
6.2.1+ds1+~cs6.1.13-16.2.1+ds1+~cs6.1.13-106.2.1+ds1+~cs6.1.13-116.2.1+ds1+~cs6.1.13-26.2.1+ds1+~cs6.1.13-3
Show 9 moreShow less
6.2.1+ds1+~cs6.1.13-46.2.1+ds1+~cs6.1.13-56.2.1+ds1+~cs6.1.13-66.2.1+ds1+~cs6.1.13-76.2.1+ds1+~cs6.1.13-86.2.1+ds1+~cs6.1.13-96.2.1+~cs7.0.8-17.5.16+~4.0.1-17.5.16+~4.0.1-2
7.5.19+~4.0.1-1
tar
npm
before 7.5.17
7.5.17
tar
Root:npm
before 7.5.11-aikido.4
7.5.11-aikido.47.4.3-aikido.12
@rootio/tar
Root:npm
before 7.5.11-root.io.4
7.5.11-root.io.47.4.3-root.io.12
node-tar
Ubuntu:Pro:14.04:LTS
All versions, plus listed versions
0.1.18-10.1.18-1ubuntu0.1~esm1
None known
node-tar
Ubuntu:Pro:16.04:LTS
All versions, plus listed versions
1.0.3-21.0.3-2ubuntu0.1~esm1
None known
node-tar
Ubuntu:18.04:LTS
All versions, plus listed versions
2.2.1-1
None known
node-tar
Ubuntu:Pro:20.04:LTS
All versions, plus listed versions
4.4.10+ds1-24.4.10+ds1-2ubuntu14.4.10+ds1-2ubuntu1+esm1
None known
node-tar
Ubuntu:22.04:LTS
All versions, plus listed versions
6.1.7+~cs11.3.10-16.1.11+~cs11.3.10-16.1.11+ds1+~cs6.0.6-1
None known
node-tar
Ubuntu:24.04:LTS
All versions, plus listed versions
6.1.13+~cs7.0.5-16.1.13+~cs7.0.5-3
None known
node-tar
Ubuntu:25.10
All versions, plus listed versions
6.2.1+~cs7.0.8-1
None known
node-tar
Ubuntu:26.10
All versions, plus listed versions
6.2.1+ds1+~cs6.1.13-107.5.22+~4.0.1-1
None known
node-tar
Ubuntu:26.04:LTS
All versions, plus listed versions
6.2.1+~cs7.0.8-16.2.1+ds1+~cs6.1.13-66.2.1+ds1+~cs6.1.13-76.2.1+ds1+~cs6.1.13-10
None known

History

History
RecordedChangedSources
affected
facts
affected
first indexedCVE List, EUVD, GitHub Advisories, NVD, OSV

Dates are when Every CVE recorded each change. Upstream dates may differ.

In short

CVE-2026-59875 is a medium vulnerability (CVSS 5.3) in Isaacs Node-tar, published April 3, 2020. No source lists public exploit code. EPSS puts the chance of exploitation in the next 30 days at 0.35%, the 29th percentile. Fixed in acorn 6.4.1.

References

Show 9 moreShow less
This page doesn't list everything

Left out here: the rest of 2 source descriptions. The JSON record has them.

MoveEnter Open