JAVASCRIPT

Secure Server-Side File Upload Validation

Implement crucial server-side validation for file uploads in Node.js, checking file type, size, and potential threats to prevent malicious content from being processed by your application.

const express = require('express');
const multer = require('multer'); // Middleware for handling multipart/form-data
const path = require('path');
const fs = require('fs');

const app = express();
const port = 3000;

// Define allowed file types and maximum file size
const allowedMimeTypes = ['image/jpeg', 'image/png', 'application/pdf'];
const maxFileSize = 5 * 1024 * 1024; // 5 MB
const uploadDir = path.join(__dirname, 'uploads');

// Ensure the upload directory exists
if (!fs.existsSync(uploadDir)) {
  fs.mkdirSync(uploadDir);
}

// Configure multer storage
const storage = multer.diskStorage({
  destination: (req, file, cb) => {
    cb(null, uploadDir); // Files will be stored in the 'uploads' directory
  },
  filename: (req, file, cb) => {
    // Generate a unique filename to prevent overwriting and path traversal attacks
    const uniqueSuffix = Date.now() + '-' + Math.round(Math.random() * 1E9);
    const fileExtension = path.extname(file.originalname);
    cb(null, file.fieldname + '-' + uniqueSuffix + fileExtension);
  }
});

// Configure multer upload with file filter and size limit
const upload = multer({
  storage: storage,
  limits: { fileSize: maxFileSize },
  fileFilter: (req, file, cb) => {
    // Validate file type
    if (!allowedMimeTypes.includes(file.mimetype)) {
      return cb(new Error('Invalid file type. Only JPEG, PNG, and PDF are allowed.'), false);
    }
    cb(null, true); // Accept the file
  }
});

// File upload endpoint
app.post('/upload', upload.single('document'), (req, res) => {
  if (req.file) {
    console.log('File uploaded:', req.file);
    res.status(200).send({
      message: 'File uploaded successfully!',
      filename: req.file.filename,
      size: req.file.size,
      mimetype: req.file.mimetype
    });
  } else {
    res.status(400).send({ message: 'No file uploaded or file upload failed.' });
  }
});

// Error handling middleware for multer errors
app.use((err, req, res, next) => {
  if (err instanceof multer.MulterError) {
    if (err.code === 'LIMIT_FILE_SIZE') {
      return res.status(400).send({ message: `File too large. Max size is ${maxFileSize / (1024 * 1024)} MB.` });
    }
    // Handle other multer errors
    return res.status(400).send({ message: `Multer error: ${err.message}` });
  } else if (err) {
    // Handle custom fileFilter errors or other generic errors
    return res.status(400).send({ message: err.message });
  }
  next();
});

app.get('/', (req, res) => {
  res.send(`
        <h1>Secure File Upload Example</h1>
        <form action="/upload" method="POST" enctype="multipart/form-data">
          <input type="file" name="document" accept="image/jpeg,image/png,application/pdf">
          <button type="submit">Upload File</button>
        </form>
        <p>Allowed types: JPEG, PNG, PDF. Max size: 5MB.</p>
      `);
});

app.listen(port, () => {
  console.log(`Server listening at http://localhost:${port}`);
});
How it works: This Node.js Express snippet demonstrates secure server-side file upload validation using the `multer` middleware. It enforces strict rules by defining allowed MIME types and a maximum file size. The `fileFilter` function explicitly checks the `mimetype` to prevent malicious file types, and the `limits` option restricts file size. Furthermore, `multer`'s `diskStorage` is configured to generate unique filenames, preventing path traversal and file overwriting vulnerabilities, ensuring only valid and safe files are processed and stored.

Need help integrating this into your project?

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

Hire DigitalCodeLabs