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.