Interview frequency: …
Short answer
Use a streaming parser (such as busboy or multer) to inspect boundaries and stream file parts while enforcing strict limits on file size and extension.
Explanation
Unlike JSON requests, multipart requests contain a boundary between fields and files. Safe handling requires avoiding loading the entire file into memory, checking the actual byte type (Magic bytes) rather than relying only on the file extension, and setting maximum sizes for fields and files to prevent denial-of-service (DoS) attacks.
Code example
import http from "node:http";
import { createWriteStream } from "node:fs";
import { randomUUID } from "node:crypto";
import busboy from "busboy";
const ALLOWED = new Set(["image/png", "image/jpeg"]);
http.createServer((req, res) => {
const bb = busboy({
headers: req.headers,
limits: { fileSize: 5 * 1024 * 1024, files: 1, fields: 5 }, // hard limits protect the server
});
bb.on("file", (field, file, info) => {
if (!ALLOWED.has(info.mimeType)) return file.resume(); // reject and drain the stream
file.pipe(createWriteStream(`/uploads/${randomUUID()}`)); // never trust the client's filename
file.on("limit", () => console.warn("file exceeded the size limit"));
});
bb.on("close", () => res.end("ok"));
req.pipe(bb); // streamed, never buffered in memory
}).listen(3000);Common mistakes
- Relying on the mimetype supplied by the browser to verify the safety of an uploaded file.