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
.
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>
Buffer
objects.I provided a patch, which was merged into Node.js 20 as commit fa5dae1944.
Equivalent to CVE-2023-30584 (report 1952978) and CVE-2023-32004 (report 2038134).