diff --git a/lib/internal/fs/utils.js b/lib/internal/fs/utils.js index b7354e30e9a6eb..6e6c7ee58cf5d1 100644 --- a/lib/internal/fs/utils.js +++ b/lib/internal/fs/utils.js @@ -712,6 +712,8 @@ function possiblyTransformPath(path) { if (permission.isEnabled()) { if (typeof path === 'string') { return pathModule.resolve(path); + } else if (Buffer.isBuffer(path)) { + return Buffer.from(pathModule.resolve(path.toString())); } } return path; diff --git a/test/fixtures/permission/fs-traversal.js b/test/fixtures/permission/fs-traversal.js index 7bf1d523dad674..288c00e537d271 100644 --- a/test/fixtures/permission/fs-traversal.js +++ b/test/fixtures/permission/fs-traversal.js @@ -8,7 +8,9 @@ const path = require('path'); const blockedFolder = process.env.BLOCKEDFOLDER; const allowedFolder = process.env.ALLOWEDFOLDER; -const traversalPath = allowedFolder + '../file.md' +const traversalPath = allowedFolder + '../file.md'; +const traversalFolderPath = allowedFolder + '../folder'; +const bufferTraversalPath = Buffer.from(allowedFolder + '../file.md'); { assert.ok(process.permission.has('fs.read', allowedFolder)); @@ -41,7 +43,33 @@ const traversalPath = allowedFolder + '../file.md' })); } +{ + assert.throws(() => { + fs.mkdtempSync(traversalFolderPath, (error) => { + assert.ifError(error); + }); + }, common.expectsError({ + code: 'ERR_ACCESS_DENIED', + permission: 'FileSystemWrite', + resource: path.toNamespacedPath(path.resolve(traversalFolderPath + 'XXXXXX')), + })); +} + +{ + assert.throws(() => { + fs.readFile(bufferTraversalPath, (error) => { + assert.ifError(error); + }); + }, common.expectsError({ + code: 'ERR_ACCESS_DENIED', + permission: 'FileSystemRead', + resource: path.resolve(traversalPath), + })); +} + { assert.ok(!process.permission.has('fs.read', traversalPath)); assert.ok(!process.permission.has('fs.write', traversalPath)); + assert.ok(!process.permission.has('fs.read', traversalFolderPath)); + assert.ok(!process.permission.has('fs.write', traversalFolderPath)); } \ No newline at end of file