Added liking and security measures
This commit is contained in:
@@ -14,6 +14,38 @@ const extensionByMimeType = {
|
||||
"image/webp": ".webp",
|
||||
};
|
||||
|
||||
// File signatures (magic bytes) that must match the declared Content-Type.
|
||||
const signatureByMimeType = {
|
||||
"image/jpeg": [Buffer.from([0xff, 0xd8, 0xff])],
|
||||
"image/png": [Buffer.from([0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a])],
|
||||
"image/gif": [Buffer.from("GIF87a"), Buffer.from("GIF89a")],
|
||||
};
|
||||
|
||||
function hasValidImageSignature(file) {
|
||||
const signatures = signatureByMimeType[file.mimetype];
|
||||
if (!signatures) {
|
||||
return isWebP(file.path);
|
||||
}
|
||||
const header = Buffer.alloc(12);
|
||||
const fd = fs.openSync(file.path, "r");
|
||||
fs.readSync(fd, header, 0, 12, 0);
|
||||
fs.closeSync(fd);
|
||||
return signatures.some((signature) =>
|
||||
header.subarray(0, signature.length).equals(signature),
|
||||
);
|
||||
}
|
||||
|
||||
function isWebP(filePath) {
|
||||
const header = Buffer.alloc(12);
|
||||
const fd = fs.openSync(filePath, "r");
|
||||
fs.readSync(fd, header, 0, 12, 0);
|
||||
fs.closeSync(fd);
|
||||
return (
|
||||
header.subarray(0, 4).equals(Buffer.from("RIFF")) &&
|
||||
header.subarray(8, 12).equals(Buffer.from("WEBP"))
|
||||
);
|
||||
}
|
||||
|
||||
fs.mkdirSync(uploadDirectory, { recursive: true });
|
||||
|
||||
const storage = multer.diskStorage({
|
||||
@@ -38,7 +70,13 @@ const ALLOWED_IMAGE_PREFIXES = ["/posts/image/", "/profiles/image/"];
|
||||
|
||||
function handleImageUpload(req, res, next) {
|
||||
uploadImage(req, res, (err) => {
|
||||
if (!err) return next();
|
||||
if (!err) {
|
||||
if (req.file && !hasValidImageSignature(req.file)) {
|
||||
fs.promises.unlink(req.file.path).catch(() => {});
|
||||
return res.status(400).send("Uploaded file is not a valid image");
|
||||
}
|
||||
return next();
|
||||
}
|
||||
if (err.code === "LIMIT_FILE_SIZE") {
|
||||
return res.status(413).send("Image exceeds the maximum allowed size");
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user