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'); } }