JAVASCRIPT

Secure File Upload Validation in Node.js

Implement robust server-side validation for file uploads, checking file types, sizes, and storing them securely to prevent common vulnerabilities.

// Install required packages: npm install express multer path uuid
const express = require('express');
const multer = require('multer');
const path = require('path');
const { v4: uuidv4 } = require('uuid'); // For unique file names
const fs = require('fs');

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

// Ensure upload directory exists
const uploadDir = path.join(__dirname, 'uploads');
if (!fs.existsSync(uploadDir)) {
    fs.mkdirSync(uploadDir);
}

// Configure Multer storage
const storage = multer.diskStorage({
    destination: (req, file, cb) => {
        // Store files outside the public web root for security
        cb(null, uploadDir); 
    },
    filename: (req, file, cb) => {
        // Generate a unique filename to prevent overwriting and path traversal
        const uniqueSuffix = uuidv4();
        const fileExtension = path.extname(file.originalname);
        cb(null, `${uniqueSuffix}${fileExtension}`);
    }
});

// Configure Multer upload middleware
const upload = multer({
    storage: storage,
    limits: { 
        fileSize: 5 * 1024 * 1024 // Limit file size to 5MB
    },
    fileFilter: (req, file, cb) => {
        // Validate file types - IMPORTANT for security
        const allowedMimeTypes = ['image/jpeg', 'image/png', 'application/pdf'];
        if (allowedMimeTypes.includes(file.mimetype)) {
            cb(null, true); // Accept file
        } else {
            cb(new Error('Invalid file type. Only JPEG, PNG, and PDF are allowed.'), false); // Reject file
        }
    }
});

// Route for file upload
app.post('/upload', upload.single('myFile'), (req, res) => {
    if (req.file) {
        res.status(200).json({ 
            message: 'File uploaded successfully!', 
            filename: req.file.filename,
            path: `/uploads/${req.file.filename}` // Do NOT return full server path
        });
    } else {
        res.status(400).json({ message: 'File upload failed or no file provided.' });
    }
}, (error, req, res, next) => { // Multer error handler
    if (error instanceof multer.MulterError) {
        if (error.code === 'LIMIT_FILE_SIZE') {
            return res.status(400).json({ message: 'File size too large. Max 5MB allowed.' });
        }
    }
    // Handle other errors, including custom fileFilter errors
    res.status(400).json({ message: error.message });
});

app.listen(PORT, () => {
    console.log(`Server running on http://localhost:${PORT}`);
});
How it works: This Node.js snippet demonstrates how to securely handle file uploads using the `multer` middleware. Key security practices include: 1) **MIME type validation** via `fileFilter` to ensure only expected file types (e.g., images, PDFs) are accepted, preventing malicious script uploads. 2) **File size limits** (`limits.fileSize`) to prevent denial-of-service attacks. 3) **Unique file naming** (`uuidv4`) to avoid overwriting existing files and prevent directory traversal. 4) **Storing files outside the public web root** to prevent direct execution by web servers. Error handling for Multer-specific issues like file size limits is also included.

Need help integrating this into your project?

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

Hire DigitalCodeLabs