In order to securely handle image uploads and sanitize them to prevent malicious payloads to enter your web application, we have several effective techniques:
1. Validate File Type and Extension:
Ensure uploaded files are only images by checking file extensions and MIME types.
const allowedTypes = ['image/jpeg', 'image/png', 'image/gif'];
if (!allowedTypes.includes(uploadedFile.mimetype)) {
throw new Error("Invalid file type");
}
2. Re-encode Images with Image Libraries:
Use libraries like ImageMagick or sharp to re-encode and resize images, which removes any malicious code.
const sharp = require('sharp');
sharp(filePath)
.resize(1000) // Resize as needed
.toFile('sanitized-output.jpg', (err, info) => { /* handle */ });
3. Set Non-Executable Permissions:
Make sure uploaded files are not executable. Use chmod to ensure the images are not executable.
chmod 0644 /path/to/uploaded/images
4. Limit File Size:
Restrict the file size to avoid large, potentially harmful files.
const maxFileSize = 5 * 1024 * 1024; // 5 MB
if (uploadedFile.size > maxFileSize) {
throw new Error("File is too large");
}
5. Strip Metadata:
Remove any embedded metadata from images (like EXIF data) to prevent hidden threats.
sharp(inputFile)
.withMetadata(false) // Strips all metadata
.toFile(outputFile);
6. Convert to Safer Formats:
Convert images to simpler formats (e.g., PNG, JPEG) to avoid any scripts or harmful code.
sharp(inputFile)
.toFormat('png')
.toFile(outputFile);
7. Check Image Dimensions:
Verify that the uploaded file is a valid image by checking its dimensions.
const sizeOf = require('image-size');
const dimensions = sizeOf(uploadedFile);
if (!dimensions.width || !dimensions.height) {
throw new Error("Invalid image file");
}
8. Scan for Malware:
Use tools like ClamAV to scan for malware in uploaded files.
clamscan /path/to/uploaded/file
9. Use a CDN for Image Delivery:
Serve images through a secure CDN to protect your server and add security layers.
10. Enforce Content Security Policy (CSP):
Use CSP to prevent scripts from running within images, adding another layer of defense