JAVASCRIPT
Implement Secure Server-Side File Uploads with Multer
Securely handle file uploads on the server in Node.js using Multer by implementing crucial validations for file types, sizes, and storing files safely outside the web root.
// Install express and multer: npm install express multer
const express = require('express');
const multer = require('multer');
const path = require('path');
const fs = require('fs');
const app = express();
// Define storage settings for Multer
const storage = multer.diskStorage({
destination: (req, file, cb) => {
const uploadDir = path.join(__dirname, 'uploads'); // Store files outside web root or in a specific directory
if (!fs.existsSync(uploadDir)) {
fs.mkdirSync(uploadDir);
}
cb(null, uploadDir);
},
filename: (req, file, cb) => {
// Generate a unique filename to prevent overwriting and path traversal
const uniqueSuffix = Date.now() + '-' + Math.round(Math.random() * 1E9);
cb(null, file.fieldname + '-' + uniqueSuffix + path.extname(file.originalname));
}
});
// Configure Multer for file upload, including security validations
const upload = multer({
storage: storage,
limits: { fileSize: 1024 * 1024 * 5 }, // Limit file size to 5MB
fileFilter: (req, file, cb) => {
// Allowed file types: images and PDFs
const allowedMimeTypes = ['image/jpeg', 'image/png', 'image/gif', 'application/pdf'];
if (allowedMimeTypes.includes(file.mimetype)) {
cb(null, true);
} else {
cb(new Error('Invalid file type. Only JPG, PNG, GIF, and PDF files are allowed.'), false);
}
}
});
// Express route for handling single file upload
app.post('/upload-single', upload.single('myFile'), (req, res) => {
if (!req.file) {
return res.status(400).send('No file uploaded.');
}
res.send(`File uploaded successfully: ${req.file.filename}`);
}, (error, req, res, next) => {
// Multer error handler
res.status(400).send({ error: error.message });
});
// app.listen(3000, () => console.log('Server running on port 3000'));
How it works: This Node.js snippet, using the `multer` middleware, demonstrates how to securely handle file uploads. It sets up `diskStorage` to save files to a designated `uploads` directory, preferably outside the public web root, and generates unique filenames to prevent path traversal and overwriting existing files. Crucially, it includes `limits` for file size and a `fileFilter` to explicitly allow only specific MIME types (e.g., images, PDFs), mitigating risks associated with malicious file uploads. Error handling is also included for invalid uploads.