From f9a5145ac5fb902f84602e84fa0c71082338ff93 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tobias=20Nie=C3=9Fen?= Date: Wed, 3 Apr 2024 15:14:35 +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 --- 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'); } }