PHP
Securely Validate File Uploads on the Server-Side
Implement robust server-side validation for file uploads in PHP to prevent malicious script execution, directory traversal, and other security vulnerabilities.
<?php
ini_set('display_errors', 1);
ini_set('display_startup_errors', 1);
error_reporting(E_ALL);
$uploadDir = __DIR__ . '/uploads/';
$allowedMimeTypes = ['image/jpeg', 'image/png', 'image/gif'];
$maxFileSize = 5 * 1024 * 1024; // 5 MB
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_FILES['uploadFile'])) {
$file = $_FILES['uploadFile'];
// 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'] > $maxFileSize) {
echo "File size exceeds the limit of " . ($maxFileSize / (1024 * 1024)) . " MB.";
exit;
}
// 3. Validate MIME type (actual content, not just extension)
$finfo = new finfo(FILEINFO_MIME_TYPE);
$mimeType = $finfo->file($file['tmp_name']);
if (!in_array($mimeType, $allowedMimeTypes)) {
echo "Invalid file type: " . htmlspecialchars($mimeType) . ". Allowed types: " . implode(', ', $allowedMimeTypes) . ".";
exit;
}
// 4. Sanitize filename and generate a unique name
$extension = pathinfo($file['name'], PATHINFO_EXTENSION);
$safeFilename = md5(uniqid(rand(), true)) . '.' . $extension; // Generate unique, random filename
$uploadPath = $uploadDir . $safeFilename;
// Ensure target directory exists and is writable
if (!is_dir($uploadDir) || !is_writable($uploadDir)) {
mkdir($uploadDir, 0755, true);
}
// 5. Move the uploaded file
if (move_uploaded_file($file['tmp_name'], $uploadPath)) {
echo "File uploaded successfully: " . htmlspecialchars($safeFilename) . "
";
} else {
echo "Failed to move uploaded file.
";
}
} else {
?>
<!DOCTYPE html>
<html>
<head><title>File Upload</title></head>
<body>
<form action="" method="post" enctype="multipart/form-data">
<input type="file" name="uploadFile" />
<input type="submit" value="Upload" />
</form>
</body>
</html>
<?php
}
?>
How it works: This PHP snippet provides a comprehensive approach to securely handling file uploads on the server-side. It's critical to validate uploaded files rigorously to prevent attackers from uploading malicious scripts (web shells), large files for DoS, or files that exploit server vulnerabilities. The process includes checking for upload errors, enforcing maximum file size limits, and crucially, validating the actual MIME type of the file's content using `finfo` (not just the file extension, which can be easily faked). Finally, it sanitizes the filename by generating a unique, random name to prevent path traversal and overwriting existing files, before safely moving the file to a designated, non-web-accessible upload directory (ideally).