From b8fad8bfc22969893511539a67f92665a730ba1f Mon Sep 17 00:00:00 2001 From: RafaelGSS Date: Mon, 29 Jul 2024 17:19:18 -0300 Subject: [PATCH 1/3] lib,permission: support Buffer to permission.has --- lib/fs.js | 6 ++++-- lib/internal/process/permission.js | 10 ++++++++-- test/fixtures/permission/fs-read.js | 6 ++++++ test/fixtures/permission/fs-traversal.js | 8 ++++++++ test/parallel/test-permission-has.js | 4 ++++ 5 files changed, 30 insertions(+), 4 deletions(-) diff --git a/lib/fs.js b/lib/fs.js index 2119554c0e72c1..570f014dcb5ec1 100644 --- a/lib/fs.js +++ b/lib/fs.js @@ -1546,7 +1546,8 @@ function lstat(path, options = { bigint: false }, callback) { callback = makeStatsCallback(callback); path = getValidatedPath(path); if (permission.isEnabled() && !permission.has('fs.read', path)) { - callback(new ERR_ACCESS_DENIED('Access to this API has been restricted', 'FileSystemRead', path)); + const resource = BufferIsBuffer(path) ? BufferToString(path) : path; + callback(new ERR_ACCESS_DENIED('Access to this API has been restricted', 'FileSystemRead', resource)); return; } @@ -1623,7 +1624,8 @@ function fstatSync(fd, options = { bigint: false }) { function lstatSync(path, options = { bigint: false, throwIfNoEntry: true }) { path = getValidatedPath(path); if (permission.isEnabled() && !permission.has('fs.read', path)) { - throw new ERR_ACCESS_DENIED('Access to this API has been restricted', 'FileSystemRead', path); + const resource = BufferIsBuffer(path) ? BufferToString(path) : path; + throw new ERR_ACCESS_DENIED('Access to this API has been restricted', 'FileSystemRead', resource); } const stats = binding.lstat( getValidatedPath(path), diff --git a/lib/internal/process/permission.js b/lib/internal/process/permission.js index f0d5f2b180b8fa..7a6dd80d1d01f3 100644 --- a/lib/internal/process/permission.js +++ b/lib/internal/process/permission.js @@ -5,7 +5,9 @@ const { } = primordials; const permission = internalBinding('permission'); -const { validateString } = require('internal/validators'); +const { validateString, validateBuffer } = require('internal/validators'); +const { Buffer } = require('buffer'); +const { isBuffer } = Buffer; let experimentalPermission; @@ -22,7 +24,11 @@ module.exports = ObjectFreeze({ validateString(scope, 'scope'); if (reference != null) { // TODO: add support for WHATWG URLs and Uint8Arrays. - validateString(reference, 'reference'); + if (isBuffer(reference)) { + validateBuffer(reference, 'reference'); + } else { + validateString(reference, 'reference'); + } } return permission.has(scope, reference); diff --git a/test/fixtures/permission/fs-read.js b/test/fixtures/permission/fs-read.js index 0ce7d65b21be1a..29594ca8b5d5a2 100644 --- a/test/fixtures/permission/fs-read.js +++ b/test/fixtures/permission/fs-read.js @@ -7,6 +7,7 @@ const fs = require('fs'); const path = require('path'); const blockedFile = process.env.BLOCKEDFILE; +const bufferBlockedFile = Buffer.from(process.env.BLOCKEDFILE); const blockedFileURL = new URL('file://' + process.env.BLOCKEDFILE); const blockedFolder = process.env.BLOCKEDFOLDER; const allowedFolder = process.env.ALLOWEDFOLDER; @@ -408,6 +409,11 @@ const regularFile = __filename; }, common.expectsError({ code: 'ERR_ACCESS_DENIED', })); + assert.throws(() => { + fs.lstatSync(bufferBlockedFile); + }, common.expectsError({ + code: 'ERR_ACCESS_DENIED', + })); // doesNotThrow fs.lstat(regularFile, (err) => { diff --git a/test/fixtures/permission/fs-traversal.js b/test/fixtures/permission/fs-traversal.js index 8f2e4c0fd55c19..34b9adb22bb068 100644 --- a/test/fixtures/permission/fs-traversal.js +++ b/test/fixtures/permission/fs-traversal.js @@ -69,6 +69,14 @@ const uint8ArrayTraversalPath = new TextEncoder().encode(traversalPath); })); } +{ + fs.lstat(bufferTraversalPath, common.expectsError({ + code: 'ERR_ACCESS_DENIED', + permission: 'FileSystemRead', + resource: path.toNamespacedPath(traversalPath), + })); +} + { fs.readFile(uint8ArrayTraversalPath, common.expectsError({ code: 'ERR_ACCESS_DENIED', diff --git a/test/parallel/test-permission-has.js b/test/parallel/test-permission-has.js index f0fb582959f721..3be45c5b2a410a 100644 --- a/test/parallel/test-permission-has.js +++ b/test/parallel/test-permission-has.js @@ -21,3 +21,7 @@ const assert = require('assert'); message: 'The "reference" argument must be of type string. Received an instance of Object', })); } + +{ + assert.ok(!process.permission.has('FileSystemWrite', Buffer.from('reference'))); +} From c95589faa187f3422df45d2fb3f64bc7b3fe6f21 Mon Sep 17 00:00:00 2001 From: RafaelGSS Date: Wed, 31 Jul 2024 14:58:57 -0300 Subject: [PATCH 2/3] fixup! lib,permission: support Buffer to permission.has --- test/fixtures/permission/fs-traversal.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/test/fixtures/permission/fs-traversal.js b/test/fixtures/permission/fs-traversal.js index 34b9adb22bb068..e84b1ad4507a22 100644 --- a/test/fixtures/permission/fs-traversal.js +++ b/test/fixtures/permission/fs-traversal.js @@ -73,7 +73,9 @@ const uint8ArrayTraversalPath = new TextEncoder().encode(traversalPath); fs.lstat(bufferTraversalPath, common.expectsError({ code: 'ERR_ACCESS_DENIED', permission: 'FileSystemRead', - resource: path.toNamespacedPath(traversalPath), + // lstat checks and throw on JS side. + // resource is only resolved on C++ (is_granted) + resource: Buffer.toString(bufferTraversalPath), })); } From 96d00cd477259f819057b77d01446cd05305c21f Mon Sep 17 00:00:00 2001 From: RafaelGSS Date: Wed, 31 Jul 2024 20:05:59 -0300 Subject: [PATCH 3/3] fixup! fixup! lib,permission: support Buffer to permission.has --- test/fixtures/permission/fs-traversal.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/fixtures/permission/fs-traversal.js b/test/fixtures/permission/fs-traversal.js index e84b1ad4507a22..764ae6692522da 100644 --- a/test/fixtures/permission/fs-traversal.js +++ b/test/fixtures/permission/fs-traversal.js @@ -75,7 +75,7 @@ const uint8ArrayTraversalPath = new TextEncoder().encode(traversalPath); permission: 'FileSystemRead', // lstat checks and throw on JS side. // resource is only resolved on C++ (is_granted) - resource: Buffer.toString(bufferTraversalPath), + resource: bufferTraversalPath.toString(), })); }