Security fixes pass #1
This commit is contained in:
parent
cb5126c947
commit
3b26292124
3
.gitignore
vendored
3
.gitignore
vendored
@ -181,4 +181,5 @@ __fixtures__
|
||||
/.data
|
||||
/.dump
|
||||
/.vscode
|
||||
/source.md
|
||||
/source.md
|
||||
SECURITY.md
|
||||
@ -68,16 +68,16 @@ export default async function ({ req }: Params): Promise<Response> {
|
||||
|
||||
const config = module.config as BunextServerRouteConfig | undefined;
|
||||
|
||||
const maxBodyBytes = config?.max_request_body_mb
|
||||
? config.max_request_body_mb * MBInBytes
|
||||
: ServerDefaultRequestBodyLimitBytes;
|
||||
|
||||
const contentLength = req.headers.get("content-length");
|
||||
|
||||
if (contentLength) {
|
||||
const size = parseInt(contentLength, 10);
|
||||
|
||||
if (
|
||||
(config?.max_request_body_mb &&
|
||||
size > config.max_request_body_mb * MBInBytes) ||
|
||||
size > ServerDefaultRequestBodyLimitBytes
|
||||
) {
|
||||
if (size > maxBodyBytes) {
|
||||
return Response.json(
|
||||
{
|
||||
success: false,
|
||||
@ -91,6 +91,26 @@ export default async function ({ req }: Params): Promise<Response> {
|
||||
},
|
||||
);
|
||||
}
|
||||
} else if (req.method !== "GET" && req.method !== "HEAD") {
|
||||
const body = await req.arrayBuffer();
|
||||
if (body.byteLength > maxBodyBytes) {
|
||||
return Response.json(
|
||||
{
|
||||
success: false,
|
||||
msg: "Request Body Too Large!",
|
||||
},
|
||||
{
|
||||
status: 413,
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
routeParams.body = JSON.parse(
|
||||
new TextDecoder().decode(body) || "{}",
|
||||
);
|
||||
}
|
||||
|
||||
const target_module = (module["default"] ||
|
||||
|
||||
@ -1,8 +1,18 @@
|
||||
import EJSON from "./ejson";
|
||||
|
||||
/**
|
||||
* # Convert Serialized Query back to object
|
||||
*/
|
||||
const DANGEROUS_KEYS = new Set(["__proto__", "constructor", "prototype"]);
|
||||
|
||||
function sanitize<T>(value: T): T {
|
||||
if (value === null || typeof value !== "object") return value;
|
||||
if (Array.isArray(value)) return value.map(sanitize) as T;
|
||||
const clean: Record<string, any> = Object.create(null);
|
||||
for (const key of Object.keys(value as Record<string, any>)) {
|
||||
if (DANGEROUS_KEYS.has(key)) continue;
|
||||
clean[key] = sanitize((value as Record<string, any>)[key]);
|
||||
}
|
||||
return clean as T;
|
||||
}
|
||||
|
||||
export default function deserializeQuery(
|
||||
query: string | { [s: string]: any }
|
||||
): {
|
||||
@ -17,12 +27,17 @@ export default function deserializeQuery(
|
||||
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);
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user