mirror of
https://github.com/Dokploy/dokploy.git
synced 2026-09-14 11:06:15 +05:00
fix(api): validate OpenAPI body size limits against Greptile findings
This commit is contained in:
parent
d11735d4cd
commit
8144e1a2fe
@ -16,17 +16,22 @@ const handler = async (req: NextApiRequest, res: NextApiResponse) => {
|
||||
return;
|
||||
}
|
||||
|
||||
// getMultipartBody (trpc-openapi) doesn't accept maxBodySize, so multipart
|
||||
// uploads have no cap unless enforced here before the handler reads the stream.
|
||||
const contentLength = Number(req.headers["content-length"] ?? 0);
|
||||
// getMultipartBody doesn't accept maxBodySize, so we cap it here instead.
|
||||
const contentLength = Number(req.headers["content-length"]);
|
||||
const isMultipart = req.headers["content-type"]?.startsWith(
|
||||
"multipart/form-data",
|
||||
);
|
||||
|
||||
if (isMultipart && !Number.isFinite(contentLength)) {
|
||||
res.status(411).json({ message: "Content-Length required" });
|
||||
return;
|
||||
}
|
||||
|
||||
const limit = isMultipart
|
||||
? OPENAPI_MAX_UPLOAD_SIZE
|
||||
: OPENAPI_MAX_JSON_BODY_SIZE;
|
||||
|
||||
if (contentLength > limit) {
|
||||
if (Number.isFinite(contentLength) && contentLength > limit) {
|
||||
res.status(413).json({ message: "Payload too large" });
|
||||
return;
|
||||
}
|
||||
|
||||
@ -14,16 +14,26 @@ export const DOKPLOY_DOCKER_PORT = process.env.DOKPLOY_DOCKER_PORT
|
||||
export const CLEANUP_CRON_JOB = "50 23 * * *";
|
||||
|
||||
// Body size limits for the OpenAPI catch-all route (pages/api/[...trpc].ts).
|
||||
// JSON/urlencoded bodies are capped by trpc-openapi's own default (100kb) unless
|
||||
// we pass an explicit limit; multipart uploads (e.g. drop-deployment zips) have
|
||||
// no built-in cap at all, so we enforce one manually via content-length.
|
||||
export const OPENAPI_MAX_JSON_BODY_SIZE = process.env.OPENAPI_MAX_JSON_BODY_SIZE
|
||||
? Number.parseInt(process.env.OPENAPI_MAX_JSON_BODY_SIZE, 10)
|
||||
: 10 * 1024 * 1024; // 10mb
|
||||
const parseByteSize = (envVar: string, fallback: number): number => {
|
||||
const raw = process.env[envVar];
|
||||
if (!raw) return fallback;
|
||||
const parsed = Number.parseInt(raw, 10);
|
||||
if (!Number.isFinite(parsed) || parsed <= 0) {
|
||||
console.warn(`Invalid ${envVar}="${raw}", using default ${fallback}`);
|
||||
return fallback;
|
||||
}
|
||||
return parsed;
|
||||
};
|
||||
|
||||
export const OPENAPI_MAX_UPLOAD_SIZE = process.env.OPENAPI_MAX_UPLOAD_SIZE
|
||||
? Number.parseInt(process.env.OPENAPI_MAX_UPLOAD_SIZE, 10)
|
||||
: 1024 * 1024 * 1024; // 1gb
|
||||
export const OPENAPI_MAX_JSON_BODY_SIZE = parseByteSize(
|
||||
"OPENAPI_MAX_JSON_BODY_SIZE",
|
||||
10 * 1024 * 1024, // 10mb
|
||||
);
|
||||
|
||||
export const OPENAPI_MAX_UPLOAD_SIZE = parseByteSize(
|
||||
"OPENAPI_MAX_UPLOAD_SIZE",
|
||||
1024 * 1024 * 1024, // 1gb
|
||||
);
|
||||
|
||||
type DockerSocketCandidate = {
|
||||
label: string;
|
||||
|
||||
Loading…
Reference in New Issue
Block a user