Lucene search

K
hackeroneTniessenH1:2225660
HistoryOct 25, 2023 - 1:58 p.m.

Internet Bug Bounty: Permission model improperly protects against path traversal in Node.js 20

2023-10-2513:58:08
tniessen
hackerone.com
$2330
30
cve-2023-30584
path traversal
node.js 20
permission model
vulnerability
hackerone
implementation
security patch
impact

7.3 High

AI Score

Confidence

Low

0.001 Low

EPSS

Percentile

22.2%

Summary: A previously disclosed vulnerability (CVE-2023-30584) was patched insufficiently in commit 205f1e6. The new path traversal vulnerability arises because the implementation does not protect itself against the application overwriting built-in utility functions with user-defined implementations.

Description: The function possiblyTransformPath calls pathModule.resolve(path), where pathModule is the result of require('path'). Application code may replace the value of the require('path').resolveproperty with a user-defined function that does not resolve /../ within any given path. Because possiblyTransformPath retrieves the value of the pathModule.resolve property dynamically, it will use the user-defined function instead of the built-in function and will thus fail to fully resolve the path given by the application. The vulnerability can be prevented by maintaining a reference to the original value of pathModule.resolve for use in possiblyTransformPath, assuming that the original implementation of the resolve() function is not subject to any such vulnerabilities itself.

Steps To Reproduce:

Temporarily assigning path.resolve = (s) => s disables the resolution of /../ within the permission model implementation.

$ node --experimental-permission --allow-fs-read=/tmp/ -p "path.resolve = (s) => s; fs.readFileSync('/tmp/../etc/passwd')"
<Buffer 72 6f 6f 74 3a 78 3a 30 3a 30 3a 72 6f 6f 74 3a 2f 72 6f 6f 74 3a 2f 62 69 6e 2f 62 61 73 68 0a 64 61 65 6d 6f 6e 3a 78 3a 31 3a 31 3a 64 61 65 6d 6f ... 3174 more bytes>

Supporting Material/References:

Suggested patch

diff --git a/lib/internal/fs/utils.js b/lib/internal/fs/utils.js
index b7354e30e9..4971656d0a 100644
--- a/lib/internal/fs/utils.js
+++ b/lib/internal/fs/utils.js
@@ -710,2 +710,3 @@ const validatePath = hideStackFrames((path, propName = 'path') => {
 // The permission model needs the absolute path for the fs_permission
+const resolvePath = pathModule.resolve;
 function possiblyTransformPath(path) {
@@ -713,3 +714,3 @@ function possiblyTransformPath(path) {
     if (typeof path === 'string') {
-      return pathModule.resolve(path);
+      return resolvePath(path);
     }

This patch assumes that pathModule.resolve() itself is not susceptible to having its behavior altered in a security-critical way through user-defined properties.

This patch was merged into the main branch of Node.js as commit 32bcf4ca and into the Node.js 20 release line as commit cd352751.

Impact

The impact is almost identical with that of CVE-2023-30584. Applications may use this vulnerability to read and write files and directories that the user has not granted access to.