Скрипт безопасной загрузки
Aug 17 2020
Я создаю социальную сеть, в которой пользователи могут загружать изображение профиля. Я просто хочу знать, является ли это безопасным способом сделать это. Благодарю.
<?php
include 'includes/header.php';
include 'includes/form_handlers/settings_handler.php';
//$userPic = ''; $date_time = date('Y-m-d_H-i-s');
if(!empty($userLoggedIn)) { if (isset($_FILES['fileToUpload'])) {
$errors= array(); $file_name = $_FILES['fileToUpload']['name']; $file_size = $_FILES['fileToUpload']['size']; $width = 1500;
$height = 1500; $file_tmp = $_FILES['fileToUpload']['tmp_name']; $file_type = $_FILES['fileToUpload']['type']; $tmp = explode('.',$_FILES['fileToUpload']['name']); $file_ext=strtolower (end ($tmp)); $extensions = array( "jpeg", "jpg", "png", "gif");
if(in_array($file_ext,$extensions)=== false){
$errors[]="extension not allowed, please choose a JPEG or PNG file."; } if ($file_size > 8097152) {
$errors[] = 'File size must be 2 MB'; } if ($width > 1500 || $height > 1500) { echo"File is to large"; } if(!$errors) {
$userPic = md5($_FILES["fileToUpload"]["name"]) . $date_time . " " . $file_name;
$profilePic = move_uploaded_file($file_tmp,"assets/images/profile_pics/" . $userPic); $file_path = "assets/images/profile_pics/" . $userPic; $stmt = $con->prepare("UPDATE users SET profile_pic = ? WHERE username = ?"); $stmt->bind_param('ss', $file_path, $username);
$stmt->execute(); $stmt->close();
header('Location: settings.php');
exit();
}
}
} else {
echo "Invalid Username";
}
?>
Ответы
5 LiamSorsby Aug 18 2020 at 21:13
Это мое личное мнение, но я бы сказал следующее:
- Код должен быть отформатирован, я бы лично посмотрел на PSR-12, поскольку этот стандарт должен соблюдаться, когда это возможно.
- move_uploaded_file не защищает от обхода каталога. Вы должны использовать базовое имя
$_FILES['fileToUpload']['tmp_name']
и некоторые другие формы проверки - Проверка расширения файла с помощью
if(in_array($file_ext,$extensions)=== false)
не мешает пользователю загружать вредоносный файл, они могут, например, использовать магический байт, чтобы заставить сервер думать, что это файл определенного типа. Вам следует взглянуть на finfo и первый пример загрузки файлов. - Вы создаете массив ошибок, который в настоящее время проверяется оператором if и затем отбрасывается. Если вы не планируете использовать его, возможно, лучше просто вернуться из функции пораньше, чем продолжать выполнение.
- В зависимости от того, насколько уникальным должно быть имя файла, вы можете использовать что-то вроде
uniqid(mt_rand(), true)
- move_uploaded_file заменит файл, если он уже существует, вы можете проверить, существует ли он, прежде чем перезаписывать существующий файл. В зависимости от вашего решения для именования это очень маловероятно, но при высокой нагрузке в течение длительных периодов времени это может происходить чаще, чем вы думаете.
- Вы используете,
UPDATE users SET profile_pic = ? WHERE username = ?
я бы предположил, что это значение существует в базе данных, так как пользователь должен войти в систему. Однако, если вы не уверены, существует ли поле или нет (я не видел базу данных), я бы лично использовать:INSERT INTO users (profile_pic, username) VALUES (?,?) ON DUPLICATE KEY UPDATE profile_pic=?, username=?
это будет вставлено в таблицу, если строка не существует, но обновит ее, если она есть. - Вы установили локальную переменную ширину и высоту и сравниваете их с одним и тем же значением. Полагаю, это было сделано для проверки реальных размеров файла?
Надеюсь, это как-то поможет :)