Fortify user data path checks
This commit is contained in:
+16
-5
@@ -16,7 +16,7 @@ import { sync as writeFileAtomicSync } from 'write-file-atomic';
|
|||||||
import sanitize from 'sanitize-filename';
|
import sanitize from 'sanitize-filename';
|
||||||
|
|
||||||
import { USER_DIRECTORY_TEMPLATE, DEFAULT_USER, PUBLIC_DIRECTORIES, SETTINGS_FILE, UPLOADS_DIRECTORY } from './constants.js';
|
import { USER_DIRECTORY_TEMPLATE, DEFAULT_USER, PUBLIC_DIRECTORIES, SETTINGS_FILE, UPLOADS_DIRECTORY } from './constants.js';
|
||||||
import { getConfigValue, color, delay, generateTimestamp, invalidateFirefoxCache } from './util.js';
|
import { getConfigValue, color, delay, generateTimestamp, invalidateFirefoxCache, isPathUnderParent } from './util.js';
|
||||||
import { readSecret, writeSecret } from './endpoints/secrets.js';
|
import { readSecret, writeSecret } from './endpoints/secrets.js';
|
||||||
import { getContentOfType } from './endpoints/content-manager.js';
|
import { getContentOfType } from './endpoints/content-manager.js';
|
||||||
import { serverDirectory } from './server-directory.js';
|
import { serverDirectory } from './server-directory.js';
|
||||||
@@ -948,7 +948,11 @@ function createRouteHandler(directoryFn) {
|
|||||||
try {
|
try {
|
||||||
const directory = directoryFn(req);
|
const directory = directoryFn(req);
|
||||||
const filePath = decodeURIComponent(req.params[0]);
|
const filePath = decodeURIComponent(req.params[0]);
|
||||||
const exists = fs.existsSync(path.join(directory, filePath));
|
const fullPath = path.join(directory, filePath);
|
||||||
|
if (!isPathUnderParent(directory, path.resolve(fullPath))) {
|
||||||
|
return res.sendStatus(403);
|
||||||
|
}
|
||||||
|
const exists = fs.existsSync(fullPath);
|
||||||
if (!exists) {
|
if (!exists) {
|
||||||
return res.sendStatus(404);
|
return res.sendStatus(404);
|
||||||
}
|
}
|
||||||
@@ -971,13 +975,20 @@ function createExtensionsRouteHandler(directoryFn) {
|
|||||||
try {
|
try {
|
||||||
const directory = directoryFn(req);
|
const directory = directoryFn(req);
|
||||||
const filePath = decodeURIComponent(req.params[0]);
|
const filePath = decodeURIComponent(req.params[0]);
|
||||||
|
const localPath = path.join(directory, filePath);
|
||||||
const existsLocal = fs.existsSync(path.join(directory, filePath));
|
if (!isPathUnderParent(directory, path.resolve(localPath))) {
|
||||||
|
return res.sendStatus(403);
|
||||||
|
}
|
||||||
|
const existsLocal = fs.existsSync(localPath);
|
||||||
if (existsLocal) {
|
if (existsLocal) {
|
||||||
return res.sendFile(filePath, { root: directory });
|
return res.sendFile(filePath, { root: directory });
|
||||||
}
|
}
|
||||||
|
|
||||||
const existsGlobal = fs.existsSync(path.join(PUBLIC_DIRECTORIES.globalExtensions, filePath));
|
const globalPath = path.join(PUBLIC_DIRECTORIES.globalExtensions, filePath);
|
||||||
|
if (!isPathUnderParent(PUBLIC_DIRECTORIES.globalExtensions, path.resolve(globalPath))) {
|
||||||
|
return res.sendStatus(403);
|
||||||
|
}
|
||||||
|
const existsGlobal = fs.existsSync(globalPath);
|
||||||
if (existsGlobal) {
|
if (existsGlobal) {
|
||||||
return res.sendFile(filePath, { root: PUBLIC_DIRECTORIES.globalExtensions });
|
return res.sendFile(filePath, { root: PUBLIC_DIRECTORIES.globalExtensions });
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user