Fix security vulnerabilities
This commit is contained in:
+43
-47
@@ -7,6 +7,7 @@ import _ from "lodash";
|
||||
import path from "path";
|
||||
import grabDirNames from "../../utils/grab-dir-names";
|
||||
import grabRelativePath from "../../utils/grab-relative-path";
|
||||
import { RequestBodyTooLargeError } from "../../utils/read-request-body";
|
||||
const { ROOT_DIR } = grabDirNames();
|
||||
export default async function ({ req }) {
|
||||
try {
|
||||
@@ -27,10 +28,6 @@ export default async function ({ req }) {
|
||||
},
|
||||
});
|
||||
}
|
||||
const routeParams = await grabRouteParams({
|
||||
req,
|
||||
query: match.query,
|
||||
});
|
||||
let module;
|
||||
const now = Date.now();
|
||||
const relative_match_path = grabRelativePath(match.filePath);
|
||||
@@ -50,54 +47,37 @@ export default async function ({ req }) {
|
||||
? config.max_request_body_mb * MBInBytes
|
||||
: ServerDefaultRequestBodyLimitBytes;
|
||||
const contentLength = req.headers.get("content-length");
|
||||
if (contentLength) {
|
||||
const size = parseInt(contentLength, 10);
|
||||
if (size > maxBodyBytes) {
|
||||
return Response.json({
|
||||
success: false,
|
||||
msg: "Request Body Too Large!",
|
||||
}, {
|
||||
status: 413,
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
});
|
||||
}
|
||||
if (contentLength && parseInt(contentLength, 10) > maxBodyBytes) {
|
||||
return bodyTooLargeResponse();
|
||||
}
|
||||
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",
|
||||
},
|
||||
});
|
||||
}
|
||||
try {
|
||||
routeParams.body = JSON.parse(new TextDecoder().decode(body) || "{}");
|
||||
}
|
||||
catch (error) {
|
||||
log.error(`Invalid JSON body for ${url.pathname}: ${error?.message}`);
|
||||
return Response.json({
|
||||
success: false,
|
||||
msg: "Invalid JSON body",
|
||||
}, {
|
||||
status: 400,
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
});
|
||||
let routeParams;
|
||||
try {
|
||||
routeParams = await grabRouteParams({
|
||||
req,
|
||||
query: match.query,
|
||||
max_body_bytes: maxBodyBytes,
|
||||
});
|
||||
}
|
||||
catch (error) {
|
||||
if (error instanceof RequestBodyTooLargeError) {
|
||||
return bodyTooLargeResponse();
|
||||
}
|
||||
throw error;
|
||||
}
|
||||
const target_module = (module["default"] ||
|
||||
module["handler"]);
|
||||
if (typeof target_module !== "function") {
|
||||
log.error(`API Route ${url.pathname} has no default or \`handler\` export`);
|
||||
return Response.json({
|
||||
success: false,
|
||||
msg: is_dev
|
||||
? `Route ${url.pathname} has no default or \`handler\` export`
|
||||
: "Internal Server Error",
|
||||
}, { status: 500 });
|
||||
}
|
||||
let res;
|
||||
try {
|
||||
res = await target_module?.({
|
||||
res = await target_module({
|
||||
...routeParams,
|
||||
});
|
||||
}
|
||||
@@ -105,7 +85,7 @@ export default async function ({ req }) {
|
||||
log.error(`API Route Error (${url.pathname}): ${error?.message}\n${error?.stack || ""}`);
|
||||
return Response.json({
|
||||
success: false,
|
||||
msg: `Route handler error: ${error?.message || "Internal Server Error"}`,
|
||||
msg: routeErrorMessage(error),
|
||||
}, {
|
||||
status: 500,
|
||||
headers: {
|
||||
@@ -138,7 +118,7 @@ export default async function ({ req }) {
|
||||
log.error(`API Route Error (${url.pathname}): ${error?.message}\n${error?.stack || ""}`);
|
||||
return Response.json({
|
||||
success: false,
|
||||
msg: `Route handler error: ${error?.message || "Internal Server Error"}`,
|
||||
msg: routeErrorMessage(error),
|
||||
}, {
|
||||
status: 500,
|
||||
headers: {
|
||||
@@ -147,3 +127,19 @@ export default async function ({ req }) {
|
||||
});
|
||||
}
|
||||
}
|
||||
function bodyTooLargeResponse() {
|
||||
return Response.json({
|
||||
success: false,
|
||||
msg: "Request Body Too Large!",
|
||||
}, { status: 413 });
|
||||
}
|
||||
/**
|
||||
* Error details can leak internals, so they are only exposed in
|
||||
* development. They are always logged server-side.
|
||||
*/
|
||||
function routeErrorMessage(error) {
|
||||
if (!isDevelopment()) {
|
||||
return "Internal Server Error";
|
||||
}
|
||||
return `Route handler error: ${error?.message || "Internal Server Error"}`;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user