From 8c0b723ccb69b76b415fb2f549c0bcb490d7126e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tobias=20Nie=C3=9Fen?= Date: Sat, 6 Apr 2024 08:37:04 +0100 Subject: [PATCH] fs,permission: make handling of buffers consistent Commit 2000c267ddff5b59d8649275a4bef9e27a5eb0ee added explicit handling of Buffers to fs.symlink, but not to fs.symlinkSync or fs.promises.symlink. This change adapts the latter two functions to behave like fs.symlink. Refs: https://github.com/nodejs/node/pull/49156 Refs: https://github.com/nodejs/node/pull/51212 PR-URL: https://github.com/nodejs/node/pull/52348 Reviewed-By: Rafael Gonzaga Reviewed-By: Marco Ippolito --- lib/fs.js | 6 +++++- lib/internal/fs/promises.js | 9 ++++++++- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/lib/fs.js b/lib/fs.js index 83c074bd579709..e857ac47f45c81 100644 --- a/lib/fs.js +++ b/lib/fs.js @@ -1793,7 +1793,11 @@ function symlinkSync(target, path, type) { if (permission.isEnabled()) { // The permission model's security guarantees fall apart in the presence of // relative symbolic links. Thus, we have to prevent their creation. - if (typeof target !== 'string' || !isAbsolute(toPathIfFileURL(target))) { + if (BufferIsBuffer(target)) { + if (!isAbsolute(BufferToString(target))) { + throw new ERR_ACCESS_DENIED('relative symbolic link target'); + } + } else if (typeof target !== 'string' || !isAbsolute(toPathIfFileURL(target))) { throw new ERR_ACCESS_DENIED('relative symbolic link target'); } } diff --git a/lib/internal/fs/promises.js b/lib/internal/fs/promises.js index 676583ffea5d00..a5df1f00b2e2bf 100644 --- a/lib/internal/fs/promises.js +++ b/lib/internal/fs/promises.js @@ -17,6 +17,7 @@ const { SymbolAsyncDispose, Uint8Array, FunctionPrototypeBind, + uncurryThis, } = primordials; const { fs: constants } = internalBinding('constants'); @@ -30,6 +31,8 @@ const { const binding = internalBinding('fs'); const { Buffer } = require('buffer'); +const { isBuffer: BufferIsBuffer } = Buffer; +const BufferToString = uncurryThis(Buffer.prototype.toString); const { codes: { @@ -985,7 +988,11 @@ async function symlink(target, path, type_) { if (permission.isEnabled()) { // The permission model's security guarantees fall apart in the presence of // relative symbolic links. Thus, we have to prevent their creation. - if (typeof target !== 'string' || !isAbsolute(toPathIfFileURL(target))) { + if (BufferIsBuffer(target)) { + if (!isAbsolute(BufferToString(target))) { + throw new ERR_ACCESS_DENIED('relative symbolic link target'); + } + } else if (typeof target !== 'string' || !isAbsolute(toPathIfFileURL(target))) { throw new ERR_ACCESS_DENIED('relative symbolic link target'); } }