Security fixes pass #2
This commit is contained in:
Vendored
-3
@@ -1,6 +1,3 @@
|
||||
/**
|
||||
* # Convert Serialized Query back to object
|
||||
*/
|
||||
export default function deserializeQuery(query: string | {
|
||||
[s: string]: any;
|
||||
}): {
|
||||
|
||||
Vendored
+20
-5
@@ -1,18 +1,33 @@
|
||||
import EJSON from "./ejson";
|
||||
/**
|
||||
* # Convert Serialized Query back to object
|
||||
*/
|
||||
const DANGEROUS_KEYS = new Set(["__proto__", "constructor", "prototype"]);
|
||||
function sanitize(value) {
|
||||
if (value === null || typeof value !== "object")
|
||||
return value;
|
||||
if (Array.isArray(value))
|
||||
return value.map(sanitize);
|
||||
const clean = Object.create(null);
|
||||
for (const key of Object.keys(value)) {
|
||||
if (DANGEROUS_KEYS.has(key))
|
||||
continue;
|
||||
clean[key] = sanitize(value[key]);
|
||||
}
|
||||
return clean;
|
||||
}
|
||||
export default function deserializeQuery(query) {
|
||||
let queryObject = typeof query == "object" ? query : Object(EJSON.parse(query));
|
||||
const keys = Object.keys(queryObject);
|
||||
for (let i = 0; i < keys.length; i++) {
|
||||
const key = keys[i];
|
||||
const value = queryObject[key];
|
||||
if (DANGEROUS_KEYS.has(key)) {
|
||||
delete queryObject[key];
|
||||
continue;
|
||||
}
|
||||
if (typeof value == "string") {
|
||||
if (value.match(/^\{|^\[/)) {
|
||||
queryObject[key] = EJSON.parse(value);
|
||||
queryObject[key] = sanitize(EJSON.parse(value));
|
||||
}
|
||||
}
|
||||
}
|
||||
return queryObject;
|
||||
return sanitize(queryObject);
|
||||
}
|
||||
|
||||
Vendored
+2
-1
@@ -1,4 +1,4 @@
|
||||
export default function grabDirNames(): {
|
||||
export type DirNames = {
|
||||
ROOT_DIR: string;
|
||||
SRC_DIR: string;
|
||||
PAGES_DIR: string;
|
||||
@@ -27,3 +27,4 @@ export default function grabDirNames(): {
|
||||
BUNX_ERROR_LOGS_DIR: string;
|
||||
BUNX_LOGS_DIR: string;
|
||||
};
|
||||
export default function grabDirNames(): DirNames;
|
||||
|
||||
Vendored
+2
@@ -1,5 +1,7 @@
|
||||
import path from "path";
|
||||
export default function grabDirNames() {
|
||||
if (global.DIR_NAMES)
|
||||
return global.DIR_NAMES;
|
||||
const ROOT_DIR = process.cwd();
|
||||
const SRC_DIR = path.join(ROOT_DIR, "src");
|
||||
const PAGES_DIR = path.join(SRC_DIR, "pages");
|
||||
|
||||
Vendored
+2
-6
@@ -1,10 +1,6 @@
|
||||
export default function isDevelopment() {
|
||||
const config = global.CONFIG;
|
||||
if (process.env.NODE_ENV == "production") {
|
||||
if (process.env.NODE_ENV === "production") {
|
||||
return false;
|
||||
}
|
||||
if (config.development) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
return Boolean(global.CONFIG?.development);
|
||||
}
|
||||
|
||||
Vendored
+4
@@ -0,0 +1,4 @@
|
||||
export default function isSafePath({ filePath, allowedDir, }: {
|
||||
filePath: string;
|
||||
allowedDir: string;
|
||||
}): boolean;
|
||||
Vendored
+15
@@ -0,0 +1,15 @@
|
||||
import { realpathSync } from "fs";
|
||||
import path from "path";
|
||||
export default function isSafePath({ filePath, allowedDir, }) {
|
||||
const resolved = path.resolve(filePath);
|
||||
if (!resolved.startsWith(allowedDir + path.sep) && resolved !== allowedDir) {
|
||||
return false;
|
||||
}
|
||||
try {
|
||||
const real = realpathSync(resolved);
|
||||
return (real.startsWith(allowedDir + path.sep) || real === allowedDir);
|
||||
}
|
||||
catch {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user