← Back to all snippets
JAVASCRIPT

Secure Server-Side File Upload Validation in Node.js

Enhance security for file uploads by implementing strict server-side validation of file types and extensions in Node.js using `multer`.

const express = require('express');
const multer = require('multer');
const path = require('path');
const app = express();

// Define allowed MIME types and file extensions
const allowedMimeTypes = [
    'image/jpeg',
    'image/png',
    'application/pdf'
];
const allowedExtensions = [
    '.jpg',
    '.jpeg',
    '.png',
    '.pdf'
];

// Configure Multer storage
const storage = multer.memoryStorage(); // Store file in memory to validate before saving

const fileFilter = (req, file, cb) => {
    // 1. Check MIME type
    if (!allowedMimeTypes.includes(file.mimetype)) {
        return cb(new Error('Invalid file type.'), false);
    }

    // 2. Check file extension
    const ext = path.extname(file.originalname).toLowerCase();
    if (!allowedExtensions.includes(ext)) {
        return cb(new Error('Invalid file extension.'), false);
    }

    // 3. Optional: More robust content-based type checking (e.g., using 'file-type' library)
    // For production, consider reading first few bytes to verify actual file type.
    // Example: if (file.mimetype === 'image/jpeg') { check first bytes for JPEG signature }

    cb(null, true); // Accept file
};

const upload = multer({
    storage: storage,
    fileFilter: fileFilter,
    limits: {
        fileSize: 5 * 1024 * 1024 // 5MB limit
    }
});

app.post('/upload', upload.single('document'), (req, res) => {
    if (!req.file) {
        return res.status(400).json({ message: 'No file uploaded or file type/extension is invalid.' });
    }

    // In a real application, save the buffer to disk or cloud storage
    // Example: fs.writeFileSync(path.join(__dirname, 'uploads', req.file.originalname), req.file.buffer);
    console.log(`File uploaded: ${req.file.originalname}, Type: ${req.file.mimetype}, Size: ${req.file.size} bytes`);

    res.status(200).json({ message: 'File uploaded successfully!', filename: req.file.originalname });
});

// Error handling middleware for multer
app.use((err, req, res, next) => {
    if (err instanceof multer.MulterError) {
        return res.status(400).json({ message: err.message });
    } else if (err) {
        return res.status(400).json({ message: err.message });
    }
    next();
});

const PORT = process.env.PORT || 3001;
app.listen(PORT, () => {
    console.log(`Server running on port ${PORT}`);
});
How it works: This Node.js snippet demonstrates robust server-side file upload validation using `multer`. It configures a `fileFilter` to strictly check both the file's MIME type and its extension against predefined allowed lists, preventing the upload of potentially malicious or unexpected file formats. Files are stored in memory (`memoryStorage`) during validation before being processed, and a file size limit is also enforced, enhancing overall application security.

Need help integrating this into your project?

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

Hire DigitalCodeLabs