PHP
Secure File Uploads: Validating File Type and Size in PHP
Implement robust security for file uploads in PHP. Strictly validate file types using MIME checks and enforce size limits on the server-side to prevent malicious uploads and system compromise effectively.
<?php
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_FILES['uploaded_file'])) {
$uploadDir = __DIR__ . '/uploads/'; // Ensure this directory exists and is writable
if (!is_dir($uploadDir)) {
mkdir($uploadDir, 0755, true);
}
$file = $_FILES['uploaded_file'];
// 1. Check for upload errors
if ($file['error'] !== UPLOAD_ERR_OK) {
echo "File upload error: " . $file['error'];
exit;
}
// 2. Validate file size (e.g., max 2MB)
$maxFileSize = 2 * 1024 * 1024; // 2 MB
if ($file['size'] > $maxFileSize) {
echo "Error: File size exceeds the maximum limit of 2MB.";
exit;
}
// 3. Validate file type (MIME type check)
// Allowed MIME types for images
$allowedMimeTypes = ['image/jpeg', 'image/png', 'image/gif', 'image/webp'];
// Use finfo to get the actual MIME type (more reliable than $file['type'])
$finfo = finfo_open(FILEINFO_MIME_TYPE);
$mimeType = finfo_file($finfo, $file['tmp_name']);
finfo_close($finfo);
if (!in_array($mimeType, $allowedMimeTypes)) {
echo "Error: Invalid file type. Only JPEG, PNG, GIF, and WebP images are allowed.";
exit;
}
// 4. Generate a unique and safe filename to prevent path traversal/overwrite
$extension = pathinfo($file['name'], PATHINFO_EXTENSION);
$newFileName = uniqid('upload_', true) . '.' . $extension;
$destination = $uploadDir . $newFileName;
// 5. Move the uploaded file
if (move_uploaded_file($file['tmp_name'], $destination)) {
echo "File uploaded successfully to: " . htmlspecialchars($newFileName);
// Further processing (e.g., store filename in database)
} else {
echo "Error moving uploaded file.";
}
} else {
// Display a simple upload form
echo '<form action="" method="post" enctype="multipart/form-data">';
echo 'Select image to upload (max 2MB, JPG, PNG, GIF, WebP):';
echo '<input type="file" name="uploaded_file" id="uploaded_file"><br>';
echo '<input type="submit" value="Upload Image" name="submit">';
echo '</form>';
}
?>
How it works: Unsecured file uploads are a significant vector for web attacks, allowing attackers to upload malicious scripts or executables. This PHP snippet demonstrates best practices for securing file uploads by performing crucial server-side validations. It checks for upload errors, enforces strict file size limits, and, most importantly, validates the actual MIME type of the file using `finfo_open` to prevent spoofed file extensions. Finally, it generates a unique, sanitized filename to prevent directory traversal and overwriting existing files, ensuring the integrity of your server.