From b59edc2428edbf470339c8cb2f0a42fb8e39665f Mon Sep 17 00:00:00 2001 From: Mark Hughes Date: Fri, 16 Aug 2024 18:38:56 +1000 Subject: [PATCH] fix: remove dependency, ensure resolved path is in scope --- package.json | 1 - packages/server/lib/services/utils.js | 46 ++++++++++++++++++++++++--- packages/server/package.json | 1 - yarn.lock | 12 ------- 4 files changed, 41 insertions(+), 19 deletions(-) diff --git a/package.json b/package.json index 996ac8c9..289acfc2 100644 --- a/package.json +++ b/package.json @@ -50,7 +50,6 @@ "send": "0.17.1", "strip-ansi": "7.0.0", "untildify": "4.0.0", - "valid-filename": "4.0.0", "which": "2.0.2", "ws": "8.2.1", "yazl": "2.5.1" diff --git a/packages/server/lib/services/utils.js b/packages/server/lib/services/utils.js index 45a8ee57..3dd8b055 100644 --- a/packages/server/lib/services/utils.js +++ b/packages/server/lib/services/utils.js @@ -10,8 +10,8 @@ const mimeTypes = require("mime-types"); const mv = require("mv"); const path = require("path"); const util = require("util"); -const validate = require("valid-filename"); -const {mkdir, stat, lstat, copyFile, readdir, access} = require("fs").promises; +const {mkdir, stat, lstat, copyFile, readdir, access} = + require("fs").promises; const paths = require("./paths.js"); @@ -26,8 +26,36 @@ const overrideMimeTypes = { "video/x-matroska": "video/webm", }; +// Regex referenced from https://github.com/sindresorhus/filename-reserved-regex +// Copyright (c) Sindre Sorhus +// LICENSE: https://github.com/sindresorhus/filename-reserved-regex/blob/main/license +const filenameReservedRegex = /[<>:"/\\|?*\u0000-\u001F]/g; +const windowsReservedNameRegex = /^(con|prn|aux|nul|com\d|lpt\d)$/i; + +// Function referenced from https://github.com/sindresorhus/valid-filename +// Copyright (c) Sindre Sorhus +// LICENSE: https://github.com/sindresorhus/valid-filename/blob/main/license +utils.isValidFilename = function(string) { + if (!string || string.length > 255) { + return false; + } + + if ( + filenameReservedRegex.test(string) || + windowsReservedNameRegex.test(string) + ) { + return false; + } + + if (string === "." || string === "..") { + return false; + } + + return true; +}; + utils.mkdir = async function(dir, cb) { - for (const d of (Array.isArray(dir) ? dir : [dir])) { + for (const d of Array.isArray(dir) ? dir : [dir]) { await mkdir(d, {mode: "755", recursive: true}); } cb(); @@ -134,7 +162,15 @@ utils.normalizePath = function(p) { }; utils.addFilesPath = function(p) { - return p === "/" ? paths.get().files : path.join(`${paths.get().files}/${p}`); + const determinedPath = fs.realpathSync( + p === "/" ? paths.get().files : path.join(paths.get().files, p) + ); + + if (!determinedPath.startsWith(paths.get().files)) { + return paths.get().files; + } + + return determinedPath; }; utils.removeFilesPath = function(p) { @@ -164,7 +200,7 @@ utils.isPathSane = function(p, isURL) { return p.split(/[\\/]/gm).every(name => { if (name === "." || name === "..") return false; if (!name) return true; - return validate(name); // will reject invalid filenames on Windows + return utils.isValidFilename(name); // will reject invalid filenames on Windows }); } }; diff --git a/packages/server/package.json b/packages/server/package.json index e728cbe7..ce2e66f6 100644 --- a/packages/server/package.json +++ b/packages/server/package.json @@ -55,7 +55,6 @@ "strip-ansi": "6.0.0", "terser": "5.2.1", "untildify": "4.0.0", - "valid-filename": "3.1.0", "which": "2.0.2", "ws": "7.4.6", "yazl": "2.5.1" diff --git a/yarn.lock b/yarn.lock index a4684605..8054841a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3170,11 +3170,6 @@ filelist@^1.0.4: dependencies: minimatch "^5.0.1" -filename-reserved-regex@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/filename-reserved-regex/-/filename-reserved-regex-3.0.0.tgz#3d5dd6d4e2d73a3fed2ebc4cd0b3448869a081f7" - integrity sha512-hn4cQfU6GOT/7cFHXBqeBg2TbrMBgdD0kcjLhvSQYYwm3s4B6cjvBfb7nBALJLAXqmU5xajSa7X2NnUud/VCdw== - fill-range@^7.0.1: version "7.0.1" resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40" @@ -7731,13 +7726,6 @@ v8-to-istanbul@^8.0.0: convert-source-map "^1.6.0" source-map "^0.7.3" -valid-filename@4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/valid-filename/-/valid-filename-4.0.0.tgz#64f1528cffa0725491de84bf1a65733c6125ab06" - integrity sha512-VEYTpTVPMgO799f2wI7zWf0x2C54bPX6NAfbZ2Z8kZn76p+3rEYCTYVYzMUcVSMvakxMQTriBf24s3+WeXJtEg== - dependencies: - filename-reserved-regex "^3.0.0" - validate-npm-package-license@3.0.4, validate-npm-package-license@^3.0.1, validate-npm-package-license@^3.0.4: version "3.0.4" resolved "https://registry.yarnpkg.com/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz#fc91f6b9c7ba15c857f4cb2c5defeec39d4f410a"