Skip to content

Commit

Permalink
lib,permission: support Buffer to permission.has
Browse files Browse the repository at this point in the history
PR-URL: #54104
Fixes: #54100
Reviewed-By: Yagiz Nizipli <yagiz@nizipli.com>
Reviewed-By: Marco Ippolito <marcoippolito54@gmail.com>
  • Loading branch information
RafaelGSS authored Aug 3, 2024
1 parent 492032f commit 358ff74
Show file tree
Hide file tree
Showing 5 changed files with 32 additions and 4 deletions.
6 changes: 4 additions & 2 deletions lib/fs.js
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

Expand Down Expand Up @@ -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),
Expand Down
10 changes: 8 additions & 2 deletions lib/internal/process/permission.js
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand All @@ -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);
Expand Down
6 changes: 6 additions & 0 deletions test/fixtures/permission/fs-read.js
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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) => {
Expand Down
10 changes: 10 additions & 0 deletions test/fixtures/permission/fs-traversal.js
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,16 @@ const uint8ArrayTraversalPath = new TextEncoder().encode(traversalPath);
}));
}

{
fs.lstat(bufferTraversalPath, common.expectsError({
code: 'ERR_ACCESS_DENIED',
permission: 'FileSystemRead',
// lstat checks and throw on JS side.
// resource is only resolved on C++ (is_granted)
resource: bufferTraversalPath.toString(),
}));
}

{
fs.readFile(uint8ArrayTraversalPath, common.expectsError({
code: 'ERR_ACCESS_DENIED',
Expand Down
4 changes: 4 additions & 0 deletions test/parallel/test-permission-has.js
Original file line number Diff line number Diff line change
Expand Up @@ -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')));
}

0 comments on commit 358ff74

Please sign in to comment.