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.

Need help integrating this into your project?

Our team of expert developers can help you build your custom application from scratch.

Hire DigitalCodeLabs