webupdatev1

This commit is contained in:
Local Server
2026-01-04 17:52:37 -06:00
parent 1919f6f8bb
commit c1da8eff42
81 changed files with 16728 additions and 475 deletions

View File

@@ -9,6 +9,55 @@ const logger = require("../config/logger");
const { uploadLimiter } = require("../config/rateLimiter");
require("dotenv").config();
// Magic bytes for image file validation
const MAGIC_BYTES = {
jpeg: [0xff, 0xd8, 0xff],
png: [0x89, 0x50, 0x4e, 0x47],
gif: [0x47, 0x49, 0x46],
webp: [0x52, 0x49, 0x46, 0x46],
};
// Validate file content by checking magic bytes
const validateFileContent = async (filePath, mimetype) => {
try {
const buffer = Buffer.alloc(8);
const fd = await fs.open(filePath, "r");
await fd.read(buffer, 0, 8, 0);
await fd.close();
// Check JPEG
if (mimetype === "image/jpeg" || mimetype === "image/jpg") {
return buffer[0] === 0xff && buffer[1] === 0xd8 && buffer[2] === 0xff;
}
// Check PNG
if (mimetype === "image/png") {
return (
buffer[0] === 0x89 &&
buffer[1] === 0x50 &&
buffer[2] === 0x4e &&
buffer[3] === 0x47
);
}
// Check GIF
if (mimetype === "image/gif") {
return buffer[0] === 0x47 && buffer[1] === 0x49 && buffer[2] === 0x46;
}
// Check WebP
if (mimetype === "image/webp") {
return (
buffer[0] === 0x52 &&
buffer[1] === 0x49 &&
buffer[2] === 0x46 &&
buffer[3] === 0x46
);
}
return false;
} catch (error) {
logger.error("Magic byte validation error:", error);
return false;
}
};
// Allowed file types
const ALLOWED_MIME_TYPES = (
process.env.ALLOWED_FILE_TYPES || "image/jpeg,image/png,image/gif,image/webp"
@@ -97,6 +146,28 @@ router.post(
const folderId = req.body.folder_id ? parseInt(req.body.folder_id) : null;
const files = [];
// Validate file content with magic bytes
for (const file of req.files) {
const isValid = await validateFileContent(file.path, file.mimetype);
if (!isValid) {
logger.warn("File upload rejected - magic byte mismatch", {
filename: file.filename,
mimetype: file.mimetype,
userId: uploadedBy,
});
// Clean up invalid file
await fs
.unlink(file.path)
.catch((err) =>
logger.error("Failed to clean up invalid file:", err)
);
return res.status(400).json({
success: false,
message: `File ${file.originalname} failed security validation`,
});
}
}
// Insert each file into database
for (const file of req.files) {
try {