Fortify user data path checks

ff8b029c9dc92d0f553eaf9dfecf117a49a4b53e

Cohee <18619528+Cohee1207@users.noreply.github.com>

1 files changed, +16 -5Ignore whitespace
src/users.js+16 -5
@@ -16,7 +16,7 @@ import { sync as writeFileAtomicSync } from 'write-file-atomic';
1616import sanitize from 'sanitize-filename';
1717
1818import { USER_DIRECTORY_TEMPLATE, DEFAULT_USER, PUBLIC_DIRECTORIES, SETTINGS_FILE, UPLOADS_DIRECTORY } from './constants.js';
1919import { getConfigValue, color, delay, generateTimestamp, invalidateFirefoxCache, isPathUnderParent } from './util.js';
2020import { readSecret, writeSecret } from './endpoints/secrets.js';
2121import { getContentOfType } from './endpoints/content-manager.js';
2222import { serverDirectory } from './server-directory.js';
@@ -948,7 +948,11 @@ function createRouteHandler(directoryFn) {
948948 try {
949949 const directory = directoryFn(req);
950950 const filePath = decodeURIComponent(req.params[0]);
951951 const existsfullPath = fs.existsSync(path.join(directory, filePath));
952+ if (!isPathUnderParent(directory, path.resolve(fullPath))) {
953+ return res.sendStatus(403);
954+ }
955+ const exists = fs.existsSync(fullPath);
952956 if (!exists) {
953957 return res.sendStatus(404);
954958 }
@@ -971,13 +975,20 @@ function createExtensionsRouteHandler(directoryFn) {
971975 try {
972976 const directory = directoryFn(req);
973977 const filePath = decodeURIComponent(req.params[0]);
974-
978+ const localPath = path.join(directory, filePath);
975- const existsLocal = fs.existsSync(path.join(directory, filePath));
979+ if (!isPathUnderParent(directory, path.resolve(localPath))) {
980+ return res.sendStatus(403);
981+ }
982+ const existsLocal = fs.existsSync(localPath);
976983 if (existsLocal) {
977984 return res.sendFile(filePath, { root: directory });
978985 }
979986
980987 const existsGlobalglobalPath = fs.existsSync(path.join(PUBLIC_DIRECTORIES.globalExtensions, filePath));
988+ if (!isPathUnderParent(PUBLIC_DIRECTORIES.globalExtensions, path.resolve(globalPath))) {
989+ return res.sendStatus(403);
990+ }
991+ const existsGlobal = fs.existsSync(globalPath);
981992 if (existsGlobal) {
982993 return res.sendFile(filePath, { root: PUBLIC_DIRECTORIES.globalExtensions });
983994 }