chore(deps): update dependency @mintlify/previewing>tar to v7 [security]#2524
Open
renovate[bot] wants to merge 1 commit into
Open
chore(deps): update dependency @mintlify/previewing>tar to v7 [security]#2524renovate[bot] wants to merge 1 commit into
renovate[bot] wants to merge 1 commit into
Conversation
renovate
Bot
deleted the
renovate/npm-mintlify-previewing-tar-vulnerability
branch
April 15, 2026 09:13
renovate
Bot
force-pushed
the
renovate/npm-mintlify-previewing-tar-vulnerability
branch
from
April 16, 2026 17:10
31d160b to
c65441e
Compare
renovate
Bot
force-pushed
the
renovate/npm-mintlify-previewing-tar-vulnerability
branch
from
April 16, 2026 17:10
c65441e to
31d160b
Compare
renovate
Bot
force-pushed
the
renovate/npm-mintlify-previewing-tar-vulnerability
branch
from
April 21, 2026 19:02
3808743 to
31d160b
Compare
renovate
Bot
force-pushed
the
renovate/npm-mintlify-previewing-tar-vulnerability
branch
from
April 21, 2026 19:02
31d160b to
3808743
Compare
renovate
Bot
force-pushed
the
renovate/npm-mintlify-previewing-tar-vulnerability
branch
from
July 19, 2026 04:23
3808743 to
6d5f7bc
Compare
renovate
Bot
force-pushed
the
renovate/npm-mintlify-previewing-tar-vulnerability
branch
from
July 21, 2026 04:39
6d5f7bc to
a2c27e0
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This PR contains the following updates:
6.2.1→7.5.19node-tar is Vulnerable to Arbitrary File Overwrite and Symlink Poisoning via Insufficient Path Sanitization
CVE-2026-23745 / GHSA-8qq5-rm4j-mr97
More information
Details
Summary
The
node-tarlibrary (<= 7.5.2) fails to sanitize thelinkpathofLink(hardlink) andSymbolicLinkentries whenpreservePathsis false (the default secure behavior). This allows malicious archives to bypass the extraction root restriction, leading to Arbitrary File Overwrite via hardlinks and Symlink Poisoning via absolute symlink targets.Details
The vulnerability exists in
src/unpack.tswithin the[HARDLINK]and[SYMLINK]methods.1. Hardlink Escape (Arbitrary File Overwrite)
The extraction logic uses
path.resolve(this.cwd, entry.linkpath)to determine the hardlink target. Standard Node.js behavior dictates that if the second argument (entry.linkpath) is an absolute path,path.resolveignores the first argument (this.cwd) entirely and returns the absolute path.The library fails to validate that this resolved target remains within the extraction root. A malicious archive can create a hardlink to a sensitive file on the host (e.g.,
/etc/passwd) and subsequently write to it, if file permissions allow writing to the target file, bypassing path-based security measures that may be in place.2. Symlink Poisoning
The extraction logic passes the user-supplied
entry.linkpathdirectly tofs.symlinkwithout validation. This allows the creation of symbolic links pointing to sensitive absolute system paths or traversing paths (../../), even when secure extraction defaults are used.PoC
The following script generates a binary TAR archive containing malicious headers (a hardlink to a local file and a symlink to
/etc/passwd). It then extracts the archive using standardnode-tarsettings and demonstrates the vulnerability by verifying that the local "secret" file was successfully overwritten.Impact
LinkandSymbolicLinktar entries from extracted packages.)Severity
CVSS:4.0/AV:L/AC:L/AT:N/PR:N/UI:A/VC:H/VI:L/VA:N/SC:H/SI:L/SA:NReferences
This data is provided by OSV and the GitHub Advisory Database (CC-BY 4.0).
Race Condition in node-tar Path Reservations via Unicode Ligature Collisions on macOS APFS
CVE-2026-23950 / GHSA-r6q2-hw4h-h46w
More information
Details
TITLE: Race Condition in node-tar Path Reservations via Unicode Sharp-S (ß) Collisions on macOS APFS
AUTHOR: Tomás Illuminati
Details
A race condition vulnerability exists in
node-tar(v7.5.3) this is to an incomplete handling of Unicode path collisions in thepath-reservationssystem. On case-insensitive or normalization-insensitive filesystems (such as macOS APFS, In which it has been tested), the library fails to lock colliding paths (e.g.,ßandss), allowing them to be processed in parallel. This bypasses the library's internal concurrency safeguards and permits Symlink Poisoning attacks via race conditions. The library uses aPathReservationssystem to ensure that metadata checks and file operations for the same path are serialized. This prevents race conditions where one entry might clobber another concurrently.In MacOS the
join(normalizeUnicode(p)),FS confuses ß with ss, but this code does not. For example:PoC
Impact
This is a Race Condition which enables Arbitrary File Overwrite. This vulnerability affects users and systems using node-tar on macOS (APFS/HFS+). Because of using
NFDUnicode normalization (in whichßandssare different), conflicting paths do not have their order properly preserved under filesystems that ignore Unicode normalization (e.g., APFS (in whichßcauses an inode collision withss)). This enables an attacker to circumvent internal parallelization locks (PathReservations) using conflicting filenames within a malicious tar archive.Remediation
Update
path-reservations.jsto use a normalization form that matches the target filesystem's behavior (e.g.,NFKD), followed by firsttoLocaleLowerCase('en')and thentoLocaleUpperCase('en').Users who cannot upgrade promptly, and who are programmatically using
node-tarto extract arbitrary tarball data should filter out allSymbolicLinkentries (as npm does) to defend against arbitrary file writes via this file system entry name collision issue.Severity
CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:L/I:H/A:LReferences
This data is provided by OSV and the GitHub Advisory Database (CC-BY 4.0).
node-tar Vulnerable to Arbitrary File Creation/Overwrite via Hardlink Path Traversal
CVE-2026-24842 / GHSA-34x7-hfp2-rc4v
More information
Details
Summary
node-tar contains a vulnerability where the security check for hardlink entries uses different path resolution semantics than the actual hardlink creation logic. This mismatch allows an attacker to craft a malicious TAR archive that bypasses path traversal protections and creates hardlinks to arbitrary files outside the extraction directory.
Details
The vulnerability exists in
lib/unpack.js. When extracting a hardlink, two functions handle the linkpath differently:Security check in
[STRIPABSOLUTEPATH]:Hardlink creation in
[HARDLINK]:Example: An application extracts a TAR using
tar.extract({ cwd: '/var/app/uploads/' }). The TAR contains entrya/b/c/d/xas a hardlink to../../../../etc/passwd.Security check resolves the linkpath relative to the entry's parent directory:
a/b/c/d/ + ../../../../etc/passwd=etc/passwd. No../prefix, so it passes.Hardlink creation resolves the linkpath relative to the extraction directory (
this.cwd):/var/app/uploads/ + ../../../../etc/passwd=/etc/passwd. This escapes to the system's/etc/passwd.The security check and hardlink creation use different starting points (entry directory
a/b/c/d/vs extraction directory/var/app/uploads/), so the same linkpath can pass validation but still escape. The deeper the entry path, the more levels an attacker can escape.PoC
Setup
Create a new directory with these files:
package.json
{ "dependencies": { "tar": "^7.5.0" } }secret.txt (sensitive file outside uploads/)
server.js (vulnerable file upload server)
create-malicious-tar.js (attacker creates exploit TAR)
Run
Impact
An attacker can craft a malicious TAR archive that, when extracted by an application using node-tar, creates hardlinks that escape the extraction directory. This enables:
Immediate (Read Attack): If the application serves extracted files, attacker can read any file readable by the process.
Conditional (Write Attack): If the application later writes to the hardlink path, it modifies the target file outside the extraction directory.
Remote Code Execution / Server Takeover
~/.ssh/authorized_keys/etc/cron.d/*,~/.crontab~/.bashrc,~/.profile.js,.php,.pyfiles/etc/systemd/system/*.service/etc/passwd(if running as root)Data Exfiltration & Corruption
.env, secretsSeverity
CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:H/I:L/A:NReferences
This data is provided by OSV and the GitHub Advisory Database (CC-BY 4.0).
Arbitrary File Read/Write via Hardlink Target Escape Through Symlink Chain in node-tar Extraction
CVE-2026-26960 / GHSA-83g3-92jg-28cx
More information
Details
Summary
tar.extract()in Nodetarallows an attacker-controlled archive to create a hardlink inside the extraction directory that points to a file outside the extraction root, using default options.This enables arbitrary file read and write as the extracting user (no root, no chmod, no
preservePaths).Severity is high because the primitive bypasses path protections and turns archive extraction into a direct filesystem access primitive.
Details
The bypass chain uses two symlinks plus one hardlink:
a/b/c/up -> ../..a/b/escape -> c/up/../..exfil(hardlink) ->a/b/escape/<target-relative-to-parent-of-extract>Why this works:
Linkpath checks are string-based and do not resolve symlinks on disk for hardlink target safety.
STRIPABSOLUTEPATHlogic in:../tar-audit-setuid - CVE/node_modules/tar/dist/commonjs/unpack.js:255../tar-audit-setuid - CVE/node_modules/tar/dist/commonjs/unpack.js:268../tar-audit-setuid - CVE/node_modules/tar/dist/commonjs/unpack.js:281Hardlink extraction resolves target as
path.resolve(cwd, entry.linkpath)and then callsfs.link(target, destination).../tar-audit-setuid - CVE/node_modules/tar/dist/commonjs/unpack.js:566../tar-audit-setuid - CVE/node_modules/tar/dist/commonjs/unpack.js:567../tar-audit-setuid - CVE/node_modules/tar/dist/commonjs/unpack.js:703Parent directory safety checks (
mkdir+ symlink detection) are applied to the destination path of the extracted entry, not to the resolved hardlink target path.../tar-audit-setuid - CVE/node_modules/tar/dist/commonjs/unpack.js:617../tar-audit-setuid - CVE/node_modules/tar/dist/commonjs/unpack.js:619../tar-audit-setuid - CVE/node_modules/tar/dist/commonjs/mkdir.js:27../tar-audit-setuid - CVE/node_modules/tar/dist/commonjs/mkdir.js:101As a result,
exfilis created inside extraction root but linked to an external file. The PoC confirms shared inode and successful read+write viaexfil.PoC
hardlink.js
Environment used for validation:
v25.4.07.5.7tar.extract({ file, cwd }))Steps:
Prepare/locate a
tarmodule. Ifrequire('tar')is not available locally, setTAR_MODULEto an absolute path to a tar package directory.Run:
TAR_MODULE="$(cd '../tar-audit-setuid - CVE/node_modules/tar' && pwd)" node hardlink.jsInterpretation:
same_inode=true: extractedexfiland external secret are the same file object.read_ok=true: readingexfilleaks external content.write_ok=true: writingexfilmodifies external file.Impact
Vulnerability type:
Who is impacted:
tardefaults.Potential outcomes:
Severity
CVSS:3.1/AV:L/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:NReferences
This data is provided by OSV and the GitHub Advisory Database (CC-BY 4.0).
tar has Hardlink Path Traversal via Drive-Relative Linkpath
CVE-2026-29786 / GHSA-qffp-2rhf-9h96
More information
Details
Summary
tar(npm) can be tricked into creating a hardlink that points outside the extraction directory by using a drive-relative link target such asC:../target.txt, which enables file overwrite outsidecwdduring normaltar.x()extraction.Details
The extraction logic in
Unpack[STRIPABSOLUTEPATH]checks for..segments before stripping absolute roots.What happens with
linkpath: "C:../target.txt":/gives['C:..', 'target.txt'], soparts.includes('..')is false.stripAbsolutePath()removesC:and rewrites the value to../target.txt.cwdand escapes one directory up.This is reachable in standard usage (
tar.x({ cwd, file })) when extracting attacker-controlled tar archives.PoC
Tested on Arch Linux with
tar@7.5.9.PoC script (
poc.cjs):Run:
Observed output:
PWNEDconfirms outside file content overwrite. Link count2confirms the extracted file and../target.txtare hardlinked.Impact
This is an arbitrary file overwrite primitive outside the intended extraction root, with the permissions of the process performing extraction.
Realistic scenarios:
Severity
CVSS:4.0/AV:L/AC:L/AT:N/PR:N/UI:P/VC:N/VI:H/VA:L/SC:N/SI:H/SA:LReferences
This data is provided by OSV and the GitHub Advisory Database (CC-BY 4.0).
node-tar Symlink Path Traversal via Drive-Relative Linkpath
CVE-2026-31802 / GHSA-9ppj-qmqm-q256
More information
Details
Summary
tar(npm) can be tricked into creating a symlink that points outside the extraction directory by using a drive-relative symlink target such asC:../../../target.txt, which enables file overwrite outsidecwdduring normaltar.x()extraction.Details
The extraction logic in
Unpack[STRIPABSOLUTEPATH]validates..segments against a resolved path that still uses the original drive-relative value, and only afterwards rewrites the storedlinkpathto the stripped value.What happens with
linkpath: "C:../../../target.txt":stripAbsolutePath()removesC:and rewrites the value to../../../target.txt.../../../target.txt) from nested patha/b/l.../target.txt).This is reachable in standard usage (
tar.x({ cwd, file })) when extracting attacker-controlled tar archives.PoC
Tested on Arch Linux with
tar@7.5.10.PoC script (
poc.cjs):Run:
Observed output:
PWNEDconfirms outside file content overwrite.readlinkandls -lconfirm the extracted symlink points outside the extraction directory.Impact
This is an arbitrary file overwrite primitive outside the intended extraction root, with the permissions of the process performing extraction.
Realistic scenarios:
Severity
CVSS:4.0/AV:L/AC:L/AT:N/PR:N/UI:N/VC:N/VI:H/VA:N/SC:N/SI:H/SA:NReferences
This data is provided by OSV and the GitHub Advisory Database (CC-BY 4.0).
node-tar applies PAX size override to intermediary GNU long-name/long-link headers, causing tar parser interpretation differential (file smuggling)
CVE-2026-53655 / GHSA-vmf3-w455-68vh
More information
Details
Summary
tar(node-tar) applies a PAX extended header'ssize=record (and other PAXoverrides) to the next header entry of any type, including intermediary
metadata headers such as a GNU long-name (
L) or long-link (K) entry. PerPOSIX pax, a PAX extended header (
x) describes the next file entry, not theintermediary extension headers that may sit between the
xheader and the fileit annotates. Because node-tar lets the PAX
sizeoverride the byte length ofan intervening
L/K/xheader, an attacker can desynchronize node-tar'sstream cursor relative to every other mainstream tar implementation
(GNU tar, libarchive/bsdtar, Python
tarfile, and the now-fixedtar-rs/astral-tokio-tar).The result is a tar parser interpretation differential (CWE-436): a single
crafted archive yields a different set of members under node-tar than under the
reference tar tools. An attacker can use this to hide a member from one parser
while it is visible to another, which defeats security tooling whose scanner and
extractor disagree on archive contents (e.g. a malware/secret scanner that lists
entries with one library while a downstream step extracts with another). node-tar
is one of the most widely deployed JavaScript tar libraries (it backs
npm's ownpackage-tarball handling and is a transitive dependency of a very large fraction
of the npm ecosystem), so the blast radius for "files that extract differently
depending on the tool" is broad.
This is the same root cause and fix that was just addressed upstream in the Rust
tar ecosystem (
tar-rs/astral-tokio-tar); node-tar carries the equivalentdefect and has no equivalent guard.
Impact
the prior tar "smuggling" advisories GHSA-j5gw-2vrg-8fgx and
GHSA-fp55-jw48-c537).
scans with node-tar and a different member list to GNU tar / libarchive /
Python tarfile (and vice versa). This lets a malicious file be hidden from a
scanner that uses a different parser than the eventual extractor, or hidden
from node-tar-based inspection while still landing on disk via a system
tar.an attacker-supplied tar with node-tar. Tar archives are routinely fetched
from untrusted sources (package registries, user uploads, CI artifacts,
container layers).
RCE; it is a building block for supply-chain / scanner-evasion attacks rather
than a standalone code-execution primitive.
Vulnerable code (file:line)
src/header.ts(compiled todist/esm/header.js:49anddist/commonjs/header.js:85in the publishedtar@7.5.15):exis the currently-accumulated PAX local extended header andgexthePAX global header. The
sizeoverride fromex/gexis appliedunconditionally to whatever header is being decoded next — there is no check
that the header being decoded is a real file entry rather than an intermediary
extension header.
src/parse.ts,[CONSUMEHEADER]constructs the next header with the currentEX/GEXapplied:and later branches on whether that header is a metadata entry.
this[EX]iscleared only in the non-meta (real file) branch:
When the stream is ordered
x (PAX, size=N) -> L (GNU long-name) -> file, theLheader is constructed withthis[EX]still set, so itssize/remainbecomes
Ninstead of theLpayload's true length. node-tar then consumesNbytes of "metadata" and resumes header parsing at the wrong offset, landing
mid-stream. Every other mainstream parser applies the PAX
sizeonly to thefollowing file entry, so they stay synchronized.
The correct behavior (and the fix shipped upstream in the Rust tar ecosystem) is
to not apply PAX
size/overrides when the entry being decoded is itself anextension header (
LGNU long-name,KGNU long-link,xPAX local,gPAXglobal).
How input reaches the sink
tar.list(),tar.extract()/tar.x(), andtar.Parse/tar.Unpackall routeevery 512-byte header block through
Header.decode(...)with thecurrently-accumulated
EX/GEX. Any consumer that parses an attacker-suppliedarchive —
tar.list,tar.extract, or piping into the streamingParser—reaches the sink. No options need to be enabled; the default code path is
affected.
Proof of concept
Archive layout (all standard, GNU-tar-producible blocks):
Generator (
make_tar.py, pure stdlib, no external deps):A negative-control archive is identical except the PAX record is
pax_record('comment', 'x')(nosize=), written topax-control.tar.End-to-end reproduction (against pinned version
tar@7.5.15, latest release)Install the published package into a clean project and parse both archives:
e2e.mjs:Verbatim output:
Reference parsers on the same
pax-desync.tar:Interpretation differential: GNU tar, libarchive (bsdtar), and Python
tarfileall extract the member
longname.txtfrompax-desync.tar, whereas node-tar7.5.15desynchronizes, raisesTAR_ENTRY_INVALID(checksum failure fromlanding mid-stream), and reports zero members. The negative control proves
the divergence is caused solely by the PAX
size=override being applied to theintermediary
Lheader — when the same archive carries a PAX record withoutsize=, node-tar parses it identically to the reference tools(
longname.txt,file_b).Suggested fix
When decoding a header, do not apply PAX
size(or other PAX overrides) if theheader being decoded is itself an extension header. Concretely, in
src/parse.tsclear/ignorethis[EX](andthis[GEX]forsize) when theheader's type is
ExtendedHeader,GlobalExtendedHeader,NextFileHasLongPath(GNU
L), orNextFileHasLongLinkpath(GNUK); equivalently, inHeader.decode, gate theex?.size ?? gex?.sizeoverride on the decoded typenot being one of those extension types. This mirrors the upstream Rust fix,
which guards
pax_sizewithis_gnu_longname || is_gnu_longlink || is_pax_local_extensions || is_pax_global_extensions.A fix PR is being prepared against a private fork and will be linked here.
Fix PR
To be linked from a private fork of the repository (the fix will not be pushed
to any public fork or to upstream during embargo).
Credits
Reported by tonghuaroot.
Severity
CVSS:4.0/AV:L/AC:L/AT:N/PR:N/UI:N/VC:N/VI:H/VA:N/SC:N/SI:N/SA:NReferences
This data is provided by OSV and the GitHub Advisory Database (CC-BY 4.0).
node-tar: Uncaught Exception DoS via NUL byte in PAX path/linkpath records
CVE-2026-59875 / GHSA-gvwx-54wh-qm9j
More information
Details
Summary
node-tarstrips trailingNULbytes from long-name (L) and long-linkpath (K) GNU extended headers but does not apply the same sanitization to equivalent fields delivered via PAX (xtypeflag) extended headers. A PAX record of the formpath=visible.txt\x00hidden.txtis parsed verbatim intoentry.pathand flows intofs.lstat()/fs.open(), which Node.js core rejects withERR_INVALID_ARG_VALUE. The throw originates inside anFSReqCallbackasync chain that is not wrapped by the consumer'sawait/try-catcharoundtar.x()— it surfaces asuncaughtExceptionand 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 documentedtry/catcherror-handling pattern.A secondary parser-differential (CWE-436) exists because
tar(1),bsdtar, and Pythontarfiletruncate the path at the firstNUL(yieldingvisible.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-183PAX KV records flow through
parseKVLine. The value half (v) is assigned directly to the result object with no sanitization for embedded NUL bytes: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\ncontainsNUL. The result is consumed byHeader/ReadEntry, whereentry.pathandentry.linkpathcarry the embedded NUL all the way tofs.lstat().Correctly-patched cousin sink —
src/parse.ts:375-388The equivalent code path for GNU L/K long-headers does strip NUL bytes:
The
parse.tsfix is the maintainer's own acknowledgement that path strings on this codepath must be NUL-stripped before reachingfs.*. The PAX path produces the identical primitive but bypasses the guard.Downstream blast radius
entry.pathandentry.linkpathare consumed in:src/unpack.ts→fs.lstat,fs.open,fs.symlink,fs.link,fs.mkdirsrc/list.ts(no crash — listing tolerates NUL in strings)ReadEntryevent that callspath.join()/fs.*onentry.pathThe 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 — PAXpath=visible.txt\x00hidden.txtpoc-null-linkpath-crash.tar— 2560 bytes — PAXlinkpath=target\x00garbage(symlink target sink)poc1-pax-prefix.py— minimal PAX-header builder (Python 3, no deps)Tarball generator (minimal repro — Python 3)
Reproduction
Observed output (verified 2026-06-23 against
tar@7.5.16)The exception bypasses the user's
try { await tar.x(...) } catch (e) { ... }block and lands in the globaluncaughtExceptionhandler. 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:
actions/cache,actions/setup-*extracting toolchains)A correctly-coded consumer that does:
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)
path=visible.txt\x00hidden.txttar -tvf)visible.txt(truncated at NUL)bsdtar -tvfvisible.txt(truncated at NUL)tarfile.list()visible.txt\x00hidden.txt(raw)tar.t({file})tar.x({file})A pre-flight validator using GNU tar or bsdtar will see a benign filename; the subsequent node-tar extraction blows up. This is exploitable against any architecture that lists-and-validates-then-extracts.
Suggested patch
Match the long-name handler in
parse.ts— strip everything from the first NUL onward inparseKVLinevalue parsing:This matches
src/parse.ts:379andsrc/parse.ts:386and closes bothpathandlinkpathsinks in one change.A defense-in-depth follow-up: add an explicit
assert(!v.includes('\0'))(or fail-softreturn set) at the top ofparseKVLineso malformed PAX records that aren't path/linkpath also can't smuggle NUL into other unanticipated consumers (e.g. third-party readers ofentry.header.atimeDate objects constructed fromNumber(v)wherevhad embedded NUL).Severity
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:LReferences
This data is provided by OSV and the GitHub Advisory Database (CC-BY 4.0).
node-tar: Negative tar entry size causes infinite loop in archive replace
CVE-2026-59874 / GHSA-8x88-c5mf-7j5w
More information
Details
Summary
A checksum-valid tar archive with a negative base-256 encoded entry size can make
tar.replace()loop forever while scanning the existing archive. Applications that update attacker-controlled tar archives can have a worker process pinned indefinitely, causing denial of service.Details
The public
tar.replace()API scans the existing archive before appending replacement entries. During this scan, it parses each tar header and advances the archive position by the parsed entry size rounded to a 512-byte block boundary.Tar supports base-256 encoded numeric fields. A crafted header can encode the entry size as
-512while still carrying a valid checksum. The replace scan accepts that parsed negative size and uses it in the position-advance calculation.For a size of
-512, the computed body skip is-512. The scan then adds the normal 512-byte header step, resulting in no net progress. The scanner repeatedly parses the same header forever and never reaches the append step.This is reachable through the supported package API when the existing archive file is attacker controlled. It does not rely on extraction, dependency behavior, or an uncaught exception.
PoC
Save as
poc.mjsin a project with the vulnerable package installed and run:Impact
An application that calls
tar.replace()on an existing archive supplied or controlled by an attacker can be forced into a non-terminating archive scan. This can consume a worker process indefinitely and cause den