Fix security vulnerabilities
This commit is contained in:
Vendored
+42
@@ -0,0 +1,42 @@
|
||||
export class RequestBodyTooLargeError extends Error {
|
||||
status = 413;
|
||||
constructor(max_bytes) {
|
||||
super(`Request body exceeds ${max_bytes} bytes`);
|
||||
this.name = "RequestBodyTooLargeError";
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Reads the whole request body, aborting as soon as it grows past
|
||||
* `max_bytes` so oversized (or chunked, length-less) bodies are never fully
|
||||
* buffered. Returns `undefined` when the request has no body.
|
||||
*/
|
||||
export default async function readRequestBody({ req, max_bytes, }) {
|
||||
if (req.method == "GET" || req.method == "HEAD" || !req.body) {
|
||||
return undefined;
|
||||
}
|
||||
const content_length = Number(req.headers.get("content-length"));
|
||||
if (content_length > max_bytes) {
|
||||
throw new RequestBodyTooLargeError(max_bytes);
|
||||
}
|
||||
const reader = req.body.getReader();
|
||||
const chunks = [];
|
||||
let total = 0;
|
||||
while (true) {
|
||||
const { done, value } = await reader.read();
|
||||
if (done)
|
||||
break;
|
||||
total += value.byteLength;
|
||||
if (total > max_bytes) {
|
||||
await reader.cancel();
|
||||
throw new RequestBodyTooLargeError(max_bytes);
|
||||
}
|
||||
chunks.push(value);
|
||||
}
|
||||
const body = new Uint8Array(total);
|
||||
let offset = 0;
|
||||
for (const chunk of chunks) {
|
||||
body.set(chunk, offset);
|
||||
offset += chunk.byteLength;
|
||||
}
|
||||
return body;
|
||||
}
|
||||
Reference in New Issue
Block a user