diff --git a/doc/api/cli.md b/doc/api/cli.md index 4c4b029cd34e..051674253915 100644 --- a/doc/api/cli.md +++ b/doc/api/cli.md @@ -173,7 +173,7 @@ $ node --permission --allow-fs-read=* index.js node:internal/child_process:388 const err = this._handle.spawn(options); ^ -Error: Access to this API has been restricted +Error: Access to this API has been restricted. Use --allow-child-process to manage permissions. at ChildProcess.spawn (node:internal/child_process:388:28) at node:internal/main/run_main_module:17:47 { code: 'ERR_ACCESS_DENIED', @@ -486,7 +486,7 @@ new WASI({ ```console $ node --permission --allow-fs-read=* index.js -Error: Access to this API has been restricted +Error: Access to this API has been restricted. Use --allow-wasi to manage permissions. at node:internal/main/run_main_module:30:49 { code: 'ERR_ACCESS_DENIED', permission: 'WASI', @@ -517,7 +517,7 @@ new Worker(__filename); ```console $ node --permission --allow-fs-read=* index.js -Error: Access to this API has been restricted +Error: Access to this API has been restricted. Use --allow-worker to manage permissions. at node:internal/main/run_main_module:17:47 { code: 'ERR_ACCESS_DENIED', permission: 'WorkerThreads' diff --git a/doc/api/permissions.md b/doc/api/permissions.md index b8610055c783..ad008c8bb6e3 100644 --- a/doc/api/permissions.md +++ b/doc/api/permissions.md @@ -68,7 +68,7 @@ restricted (the listener for SIGUSR1 won't be created). ```console $ node --permission index.js -Error: Access to this API has been restricted +Error: Access to this API has been restricted. Use --allow-fs-read to manage permissions. at node:internal/main/run_main_module:23:47 { code: 'ERR_ACCESS_DENIED', permission: 'FileSystemRead', diff --git a/doc/node.1 b/doc/node.1 index 0c0fa769a48d..35199e39d5b1 100644 --- a/doc/node.1 +++ b/doc/node.1 @@ -102,7 +102,7 @@ $ node --permission --allow-fs-read=* index.js node:internal/child_process:388 const err = this._handle.spawn(options); ^ -Error: Access to this API has been restricted +Error: Access to this API has been restricted. Use --allow-child-process to manage permissions. at ChildProcess.spawn (node:internal/child_process:388:28) at node:internal/main/run_main_module:17:47 { code: 'ERR_ACCESS_DENIED', @@ -306,7 +306,7 @@ new WASI({ .Bd -literal $ node --permission --allow-fs-read=* index.js -Error: Access to this API has been restricted +Error: Access to this API has been restricted. Use --allow-wasi to manage permissions. at node:internal/main/run_main_module:30:49 { code: 'ERR_ACCESS_DENIED', permission: 'WASI', @@ -327,7 +327,7 @@ new Worker(__filename); .Bd -literal $ node --permission --allow-fs-read=* index.js -Error: Access to this API has been restricted +Error: Access to this API has been restricted. Use --allow-worker to manage permissions. at node:internal/main/run_main_module:17:47 { code: 'ERR_ACCESS_DENIED', permission: 'WorkerThreads' diff --git a/lib/fs.js b/lib/fs.js index 9f6cfbddb657..7b01ea364942 100644 --- a/lib/fs.js +++ b/lib/fs.js @@ -2021,8 +2021,12 @@ function lstat(path, options = { __proto__: null, bigint: false }, callback) { path = getValidatedPath(path); if (permission.isEnabled() && !permission.has('fs.read', path) && !permission.isAuditMode()) { - const resource = BufferIsBuffer(path) ? BufferToString(path) : path; - callback(new ERR_ACCESS_DENIED('Access to this API has been restricted', 'FileSystemRead', resource)); + const resource = pathModule.toNamespacedPath(BufferIsBuffer(path) ? BufferToString(path) : path); + callback(new ERR_ACCESS_DENIED( + 'Access to this API has been restricted. Use --allow-fs-read to manage permissions.', + 'FileSystemRead', + resource, + )); return; } @@ -2146,8 +2150,12 @@ function lstatSync(path, options = { __proto__: null, bigint: false, throwIfNoEn path = getValidatedPath(path); if (permission.isEnabled() && !permission.has('fs.read', path) && !permission.isAuditMode()) { - const resource = BufferIsBuffer(path) ? BufferToString(path) : path; - throw new ERR_ACCESS_DENIED('Access to this API has been restricted', 'FileSystemRead', resource); + const resource = pathModule.toNamespacedPath(BufferIsBuffer(path) ? BufferToString(path) : path); + throw new ERR_ACCESS_DENIED( + 'Access to this API has been restricted. Use --allow-fs-read to manage permissions.', + 'FileSystemRead', + resource, + ); } const stats = binding.lstat( path, diff --git a/lib/internal/fs/promises.js b/lib/internal/fs/promises.js index 47574a5a4711..10855ca532dd 100644 --- a/lib/internal/fs/promises.js +++ b/lib/internal/fs/promises.js @@ -1882,7 +1882,11 @@ async function lstat(path, options = { __proto__: null, bigint: false }) { if (permission.isEnabled() && !permission.has('fs.read', path) && !permission.isAuditMode()) { const resource = pathModule.toNamespacedPath(BufferIsBuffer(path) ? BufferToString(path) : path); - throw new ERR_ACCESS_DENIED('Access to this API has been restricted', 'FileSystemRead', resource); + throw new ERR_ACCESS_DENIED( + 'Access to this API has been restricted. Use --allow-fs-read to manage permissions.', + 'FileSystemRead', + resource, + ); } const result = await raceWithSignal( PromisePrototypeThen( diff --git a/test/fixtures/permission/fs-read.js b/test/fixtures/permission/fs-read.js index 2feb64d021b5..3d7dd01ace01 100644 --- a/test/fixtures/permission/fs-read.js +++ b/test/fixtures/permission/fs-read.js @@ -680,39 +680,60 @@ const regularFile = __filename; assert.rejects(async () => { await fsPromises.lstat(blockedFile); }, common.expectsError({ + message: 'Access to this API has been restricted. Use --allow-fs-read to manage permissions.', code: 'ERR_ACCESS_DENIED', permission: 'FileSystemRead', + resource: path.toNamespacedPath(blockedFile), })).then(common.mustCall()); assert.rejects(async () => { await fsPromises.lstat(blockedFileURL); }, common.expectsError({ + message: 'Access to this API has been restricted. Use --allow-fs-read to manage permissions.', code: 'ERR_ACCESS_DENIED', permission: 'FileSystemRead', + resource: path.toNamespacedPath(blockedFile), })).then(common.mustCall()); assert.rejects(async () => { await fsPromises.lstat(path.join(blockedFolder, 'anyfile')); }, common.expectsError({ + message: 'Access to this API has been restricted. Use --allow-fs-read to manage permissions.', code: 'ERR_ACCESS_DENIED', permission: 'FileSystemRead', + resource: path.toNamespacedPath(path.join(blockedFolder, 'anyfile')), })).then(common.mustCall()); } // fs.lstat { + fs.lstat(blockedFile, common.expectsError({ + message: 'Access to this API has been restricted. Use --allow-fs-read to manage permissions.', + code: 'ERR_ACCESS_DENIED', + permission: 'FileSystemRead', + resource: path.toNamespacedPath(blockedFile), + })); assert.throws(() => { fs.lstatSync(blockedFile); }, common.expectsError({ + message: 'Access to this API has been restricted. Use --allow-fs-read to manage permissions.', code: 'ERR_ACCESS_DENIED', + permission: 'FileSystemRead', + resource: path.toNamespacedPath(blockedFile), })); assert.throws(() => { fs.lstatSync(bufferBlockedFile); }, common.expectsError({ + message: 'Access to this API has been restricted. Use --allow-fs-read to manage permissions.', code: 'ERR_ACCESS_DENIED', + permission: 'FileSystemRead', + resource: path.toNamespacedPath(blockedFile), })); assert.throws(() => { fs.lstatSync(path.join(blockedFolder, 'anyfile')); }, common.expectsError({ + message: 'Access to this API has been restricted. Use --allow-fs-read to manage permissions.', code: 'ERR_ACCESS_DENIED', + permission: 'FileSystemRead', + resource: path.toNamespacedPath(path.join(blockedFolder, 'anyfile')), })); // doesNotThrow