Безопасный способ загрузки изображений php и GIF
Aug 20 2020
Я создаю социальную сеть и хочу знать, является ли это безопасным способом загрузки фото / гифок и видео.
if(isset($_POST['post'])) { $uploadOk = 1;
$imageName = $_FILES['postToUpload']['name'];
$errorMessage = ""; $picdate = date('Y-m-d_H-i-s');
if($imageName != "") { $targetDir = "assets/images/posts/";
$imageName = $targetDir . uniqid() . basename($imageName); $imageFileType = pathinfo($imageName, PATHINFO_EXTENSION); if($_FILES['postToUpload']['size'] > 10971520) {
$errorMessage = "Your file is to large"; $uploadOk = 0;
}
if (strtolower($imageFileType) != "jpeg" && strtolower($imageFileType) != "png" &&
strtolower($imageFileType) != "jpg" && strtolower($imageFileType) != "gif"
&& strtolower($imageFileType) != "mp4"&& strtolower($imageFileType) != "Ogg"
&& strtolower($imageFileType) != "WebM"){ $errorMessage = "File type not allowed.";
$uploadOk = 0; } if($uploadOk){
if(move_uploaded_file($_FILES['postToUpload']['tmp_name'], $imageName)) {
// image uploaded
} else{
// image did not upload
$uploadOk = 0; } } } if($uploadOk) {
$post = new Post($con, $userLoggedIn); $post->submitPost(trim(strip_tags(filter_var($_POST['post_text'], FILTER_SANITIZE_STRING))), 'none', $imageName);
} else {
echo "<div class='alert alert-danger'>
$errorMessage
</div>";
}
}
Ответы
2 Victor Sep 11 2020 at 20:56
Ваш код небезопасен, потому что:
- Он полагается только на расширение файла, поэтому злоумышленники могут загружать любые бэкдоры.
- Он обращается к переменной,
$_FILES['postToUpload']['name']
не проверяя, определена ли она, и это может привести к раскрытию полного пути. - Он использует функцию
uniqid()
без каких-либо аргументов, поэтому уникальность не гарантируется, а файлы, которые загружаются одновременно и имеют одинаковое имя, будут перезаписаны. - Он сохраняет имя файла, предоставленное пользователем, без удаления потенциально опасных символов, и это может привести к неожиданным результатам.
Некоторые рекомендации по улучшению вашего кода:
- Избавьтесь от
$uploadOk
переменной. У вас уже есть и обрабатывается$errorMessage
переменная, и этого достаточно, чтобы проверить, успешно ли был загружен файл. - Вы должны использовать
$imageFileType
строчные буквы вместо вызоваstrtolower()
каждого расширения. - Вы должны определить все допустимые расширения файлов в нижнем регистре, иначе пользователи не смогут загружать некоторые файлы (в вашем случае
WebM
иOgg
, потому чтоstrtolower($imageFileType) != "Ogg"
иstrtolower($imageFileType) != "WebM"
всегда будутFALSE
).