Проверка изображений перед загрузкой на сервер

max74max

Новичок
Здравствуйте.
Нужен взгляд профессионалов.
Есть код загрузки изображений.
Достаточно ли проверок для безопасной загрузки на сервер?

PHP:
$imgUrl = $_POST['imgUrl'];
$imgInitW = $_POST['imgInitW'];
$imgInitH = $_POST['imgInitH'];
$imgW = $_POST['imgW'];
$imgH = $_POST['imgH'];
$imgY1 = $_POST['imgY1'];
$imgX1 = $_POST['imgX1'];
$cropW = $_POST['cropW'];
$cropH = $_POST['cropH'];
$angle = $_POST['rotation'];

$jpeg_quality = 90;

$output_filename = "temp/".time()."_".rand(100,999);

$what = getimagesize($imgUrl);

if($what['0'] < "100"){
die();
}
if($what['1'] < "100"){
die();
}

switch(strtolower($what['mime']))
{
    case 'image/png':
        $img_r = imagecreatefrompng($imgUrl);
        $source_image = imagecreatefrompng($imgUrl);
        $type = '.png';
        break;
    case 'image/jpeg':
        $img_r = imagecreatefromjpeg($imgUrl);
        $source_image = imagecreatefromjpeg($imgUrl);
        error_log("jpg");
        $type = '.jpeg';
        break;
    case 'image/gif':
        $img_r = imagecreatefromgif($imgUrl);
        $source_image = imagecreatefromgif($imgUrl);
        $type = '.gif';
        break;
    default: die('image type not supported');
}

if(!is_writable(dirname($output_filename))){
    $response = Array(
        "status" => 'error',
        "message" => 'Can`t write cropped File'
    );    
}else{
    $resizedImage = imagecreatetruecolor($imgW, $imgH);
    imagecopyresampled($resizedImage, $source_image, 0, 0, 0, 0, $imgW, $imgH, $imgInitW, $imgInitH);
    $rotated_image = imagerotate($resizedImage, -$angle, 0);
    $rotated_width = imagesx($rotated_image);
    $rotated_height = imagesy($rotated_image);
    $dx = $rotated_width - $imgW;
    $dy = $rotated_height - $imgH;
    $cropped_rotated_image = imagecreatetruecolor($imgW, $imgH);
    imagecolortransparent($cropped_rotated_image, imagecolorallocate($cropped_rotated_image, 0, 0, 0));
    imagecopyresampled($cropped_rotated_image, $rotated_image, 0, 0, $dx / 2, $dy / 2, $imgW, $imgH, $imgW, $imgH);
    $final_image = imagecreatetruecolor($cropW, $cropH);
    imagecolortransparent($final_image, imagecolorallocate($final_image, 0, 0, 0));
    imagecopyresampled($final_image, $cropped_rotated_image, 0, 0, $imgX1, $imgY1, $cropW, $cropH, $cropW, $cropH);
    imagejpeg($final_image, $output_filename.$type, $jpeg_quality);
    $response = Array(
        "status" => 'success',
        "url" => $output_filename.$type
    );
imagedestroy($final_image);
}
print json_encode($response);
 

weregod

unserializer
так $_POST дерьмом (строками, числами с плавающей запятой, отрицательными числами, массивами) позаполняйте и посмотрите, как вести себя будет
кстати, молча die делать такое себе
 

max74max

Новичок
По сути, тут 2 проверки. На MIME и на размер изображения. Если это вирус, значит $what['0'] < "100", а значит die(); и вирус не проходит. Вот я и спрашиваю, достаточно ли этого для проверки, чтобы какой-нибудь умник не загрузил вирусный файл с измененным MIME под видом картинки.
Может для надежности добавить imagecopyresized() оно вроде как обновит MIME или это уже лишнее?
 

grigori

( ͡° ͜ʖ ͡°)
Команда форума
Нет, эта проверка не связана с троянами в картинках. Вирус вполне может быть размещен в нормальном файле с изображением.
От троянов в картинках надо защищаться настройкой веб-сервера. Хранить загруженные пользователем изображения надо в папке, из которой сервер не отдает картинки, и не сможет обработать файл картинки как php-скрипт. Раздавать надо обработанные изображения с обрезанной мета-информацией.
Однако, остается опасность zip-бомбы в gif и png.
 

Фанат

oncle terrible
Команда форума
проверка нормальная, только очень многословная. зачем-то куча лишнего кода. например зачем-то картинка создается по два раза
ну и ты говоришь о проверке ПОСЛЕ загрузки файла, на сервер,а не до.
 

max74max

Новичок
Вирус вполне может быть размещен в нормальном файле с изображением.
Вот в этом и суть. Но разве моя проверка на MIME не отсекает возможность загрузки таких вирусов-картинок

Хранить загруженные пользователем изображения надо в папке, из которой сервер не отдает картинки
Не совсем понял. В папку на сервер загружается скриптом картинка и из этой же папки она идет в html на вывод пользователю.
Единственное что там еще есть в этой папке, это файл .htaccess с кодом
Код:
<FilesMatch ".*">
   Order allow,deny
   Deny from all
</FilesMatch>

Options All -Indexes

order deny,allow
deny from all
allow from 127.0.0.1

Раздавать надо обработанные изображения с обрезанной мета-информацией.
А разве в моем случае после imagecopyresampled() мета-информация не измениться? Она же должна поменяться, вроде.


Однако, остается опасность zip-бомбы в gif и png.
А как от этого защититься?
 

max74max

Новичок
проверка нормальная, только очень многословная. зачем-то куча лишнего кода. например зачем-то картинка создается по два раза
ну и ты говоришь о проверке ПОСЛЕ загрузки файла, на сервер,а не до.
Да, но главное чтобы защититься от вирусов в кортиках, о про которые написал grigori
 

Фанат

oncle terrible
Команда форума
Дядя троллит, не слушай его.

То что по ссылке, к твоему коду не имеет отношения. Ты бы прочитал сначала что там написано.

А вот в .htaccess очень смешной код
когда выложишь сайт на хостинг - посмеёшься тоже
 

max74max

Новичок
То что по ссылке, к твоему коду не имеет отношения. Ты бы прочитал сначала что там написано.
Если по его ссылке, то я понял что там не имеет отношения к моему коду.
Но вот это имеет https://www.securitylab.ru/analytics/472887.php

А вот в .htaccess очень смешной код
когда выложишь сайт на хостинг - посмеёшься тоже
Вы про это? allow from 127.0.0.1 🙂
 

Фанат

oncle terrible
Команда форума
"Вот это" не имеет.
еще раз рекомендую прочесть что там написано
Осиль хотя бы первые пять абзацев
 

grigori

( ͡° ͜ʖ ͡°)
Команда форума
проверка нормальная, только очень многословная. зачем-то куча лишнего кода. например зачем-то картинка создается по два раза
ну и ты говоришь о проверке ПОСЛЕ загрузки файла, на сервер,а не до.
проверки я не вижу вообще, я вижу 2 чтения imagecreatefrompng() и несколько манипуляций imagecreatetruecolor(), imagecopyresampled() - что само по себе очевидная дырка для DDOS
 

grigori

( ͡° ͜ʖ ͡°)
Команда форума
Вот в этом и суть. Но разве моя проверка на MIME не отсекает возможность загрузки таких вирусов-картинок
я не помню, сохраняются ли meta-данные при твоих манипуляциях, к сожалению

Не совсем понял. В папку на сервер загружается скриптом картинка и из этой же папки она идет в html на вывод пользователю.
Единственное что там еще есть в этой папке, это файл .htaccess с кодом
Процесс загрузки файла на сервер немного сложнее, прочти документацию.

PHP:
$img_r = imagecreatefrompng($imgUrl);
Ты получаешь файл картинки POST-запросом, или получаешь в скрипт URL, из которого уже загружаешь картинку в скрипт?
 

max74max

Новичок
Ты получаешь файл картинки POST-запросом, или получаешь в скрипт URL, из которого уже загружаешь картинку в скрипт?
Получаю POST-запросом.

проверки я не вижу вообще
А как же
PHP:
if($what['0'] < "100"){
die();
}
Если это если это вредоносный файл, даже с MIME как у изображений, а не картинка. То у него явно будет ширина < 100, а значит die();

imagecreatetruecolor(), imagecopyresampled() - что само по себе очевидная дырка для DDOS
Что посоветуете в связи с этим?
 

max74max

Новичок
"Вот это" не имеет.
еще раз рекомендую прочесть что там написано
Осиль хотя бы первые пять абзацев
В этой статье меня насторожил тот момент, что можно в изображения внедрить код, который будет выполнятся на сервере, при этом сама картинка останется картинкой. Это как? Так вообще возможно?
 

grigori

( ͡° ͜ʖ ͡°)
Команда форума
это начинает напоминать анекдот про техподдержку
- девушка, до меня не доходят сообщения!
- прочтите их еще раз

если ты сам привел ссылку на статью о том, как внедрять код в картинку, зачем спрашивать, можно ли так сделать?
 
Сверху