JAVASCRIPT
Securely Handling File Uploads (Node.js/Express with Multer)
Implement robust and secure file upload functionality in your Node.js Express application using Multer, including file type validation, size limits, and renaming.
const express = require('express');
const multer = require('multer');
const path = require('path');
const fs = require('fs');
const app = express();
// Define the upload directory
const uploadDir = 'uploads/';
if (!fs.existsSync(uploadDir)) {
fs.mkdirSync(uploadDir);
}
// Configure Multer storage
const storage = multer.diskStorage({
destination: function (req, file, cb) {
cb(null, uploadDir);
},
filename: function (req, file, cb) {
// Generate a unique filename to prevent overwriting and path traversal attacks
const uniqueSuffix = Date.now() + '-' + Math.round(Math.random() * 1E9);
// Use path.extname to get original extension securely
cb(null, file.fieldname + '-' + uniqueSuffix + path.extname(file.originalname));
}
});
// Configure Multer upload options with security best practices
const upload = multer({
storage: storage,
limits: { fileSize: 5 * 1024 * 1024 }, // Limit file size to 5MB
fileFilter: function (req, file, cb) {
// Validate file type (MIME type and extension)
const filetypes = /jpeg|jpg|png|gif|pdf/;
const mimetype = filetypes.test(file.mimetype);
const extname = filetypes.test(path.extname(file.originalname).toLowerCase());
if (mimetype && extname) {
return cb(null, true);
} else {
cb(new Error('Error: Only images (JPEG, PNG, GIF) and PDFs are allowed!'));
}
}
}).single('myFile'); // 'myFile' is the name of the input field in the form
// Example Route for file upload
app.post('/upload', (req, res) => {
upload(req, res, function (err) {
if (err instanceof multer.MulterError) {
// A Multer error occurred when uploading.
return res.status(400).send(`Multer error: ${err.message}`);
} else if (err) {
// An unknown error occurred when uploading.
return res.status(400).send(`Upload error: ${err.message}`);
}
// Everything went fine.
res.send(`File uploaded successfully: ${req.file.filename}`);
});
});
// Example HTML form for testing (can be served by another route or a static file)
/*
<form action="/upload" method="post" enctype="multipart/form-data">
<input type="file" name="myFile" />
<button type="submit">Upload</button>
</form>
*/
const PORT = process.env.PORT || 3000;
app.listen(PORT, () => {
console.log(`Server running on port ${PORT}`);
});
How it works: This Node.js Express snippet illustrates how to securely handle file uploads using the 'multer' middleware. File uploads are a common attack vector, so robust security measures are critical. This example includes: 1) Limiting file size to prevent denial-of-service attacks, 2) Validating file types by both MIME type and file extension to prevent execution of malicious scripts (e.g., uploading a .php or .exe file disguised as an image), and 3) Generating unique, non-user-controlled filenames to prevent directory traversal and overwriting existing files. It also creates the upload directory if it doesn't exist. Always scan uploaded files for malware if possible.