File Upload Security
Validate MIME type via finfo (not file extension), limit size, store outside webroot, and serve through a controller — never execute uploaded files.
Validate MIME type via finfo (not file extension), limit size, store outside webroot, and serve through a controller — never execute uploaded files.
$file = $_FILES["upload"];
$max = 5 * 1024 * 1024; // 5MB
if ($file["size"] > $max) die("Too large");
$finfo = new finfo(FILEINFO_MIME_TYPE);
$mime = $finfo->file($file["tmp_name"]);
$allowed = ["image/jpeg", "image/png", "image/webp"];
if (!in_array($mime, $allowed, true)) die("Invalid type");
$name = bin2hex(random_bytes(16)) . ".jpg"; // random filename
move_uploaded_file($file["tmp_name"], "/storage/uploads/" . $name);
Never use the user-supplied filename — generate a random name to prevent path traversal and overwriting.