← Back to all snippets
PHP

Robust Server-Side File Upload Validation in PHP

Secure your application from malicious file uploads by implementing comprehensive server-side validation for file types, sizes, and potential threats in PHP.

<?php
define('UPLOAD_DIR', '/path/to/secure/uploads/');
define('MAX_FILE_SIZE', 2 * 1024 * 1024); // 2 MB
define('ALLOWED_MIMES', ['image/jpeg', 'image/png', 'application/pdf']);

if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_FILES['user_file'])) {
    $file = $_FILES['user_file'];

    // 1. Check for upload errors
    if ($file['error'] !== UPLOAD_ERR_OK) {
        echo "File upload error: " . $file['error'];
        exit;
    }

    // 2. Validate file size
    if ($file['size'] > MAX_FILE_SIZE) {
        echo "Error: File size exceeds the limit.";
        exit;
    }

    // 3. Validate MIME type (more reliable than extension for security)
    $finfo = finfo_open(FILEINFO_MIME_TYPE);
    $mime_type = finfo_file($finfo, $file['tmp_name']);
    finfo_close($finfo);

    if (!in_array($mime_type, ALLOWED_MIMES)) {
        echo "Error: Invalid file type detected ({$mime_type}).";
        exit;
    }

    // 4. Generate a unique and safe filename to prevent path traversal/overwrite
    $extension = pathinfo($file['name'], PATHINFO_EXTENSION);
    $sanitized_filename = uniqid('upload_', true) . '.' . strtolower($extension);
    $destination = UPLOAD_DIR . $sanitized_filename;

    // Ensure the upload directory exists and is writable
    if (!is_dir(UPLOAD_DIR) || !is_writable(UPLOAD_DIR)) {
        echo "Error: Upload directory is not configured correctly.";
        exit;
    }

    // 5. Move the uploaded file to its final destination
    if (move_uploaded_file($file['tmp_name'], $destination)) {
        echo "File uploaded successfully: " . htmlspecialchars($sanitized_filename);
        // Further processing, e.g., store filename in database
    } else {
        echo "Error: Failed to move uploaded file.";
    }
} else {
    echo "<form method='POST' enctype='multipart/form-data'>
            <input type='file' name='user_file'><br>
            <input type='submit' value='Upload File'>
          </form>";
}
How it works: This PHP snippet demonstrates robust server-side validation for file uploads. It includes checks for common vulnerabilities: ensuring no upload errors occurred, validating the file size against a maximum limit, and critically, verifying the file's MIME type using `finfo_file` (more secure than just file extensions). A unique, sanitized filename is generated to prevent path traversal and overwriting existing files. Finally, the file is moved to a designated secure upload directory only if all checks pass, protecting the server from malicious content.

Need help integrating this into your project?

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

Hire DigitalCodeLabs