Вот код в upload_processor.php
:
include_once 'functions.php'; $name = $_FILES['upload-image']['name']; $type = $_FILES['upload-image']['type']; $size = $_FILES['upload-image']['size']; $temp = $_FILES['upload-image']['tmp_name']; $error = $_FILES['upload-image']['error']; img_processor($temp, $error, $size)
И вот functions.php
:
function img_processor($img_temp, $img_error, $img_size){ if($img_error===0){ if($img_size < 4194304){ if( $proc_img = @imagecreatefromjpeg($img_temp) ){ imagejpeg($proc_img,'../uploaded/something.jpeg'); } elseif( $proc_img = @imagecreatefrompng($img_temp) ){ imagepng($proc_img,'../uploaded/something.png'); } elseif( $proc_img = @imagecreatefromgif($img_temp) ){ imagegif($proc_img,'../uploaded/something.gif'); } else { echo("Only JPEGs, PNGs, and GIFs are allowed"); } if(isset($proc_img)){ echo("upload complete"); } } else { echo("Your file was too big. Only images that are 4MB or less are allowed"); } } else { echo('Error uploading file! Code '.$img_error); } }
Основная идея – воссоздать образ, а затем переименовать его, чтобы никто не мог загружать что-то вроде malicious_code.php.jpg
.
Каковы дыры в этом коде? Есть ли лучшие способы защитить мой сайт от изображений, вложенных в PHP?
imagegreatefrom*
вернет false, если есть ошибка, поэтому оператор @
самом деле не делает много в этой ситуации.
Вместо вызова imagecreatefrom*
вы можете проверить, действительно ли входной файл действителен с использованием exif_imagetype
а затем вызвать соответствующий обработчик. Я не уверен, что есть последствия для безопасности (хотя интуитивно кажется, что могут возникнуть проблемы с безопасностью с вышеуказанным кодом), но производительность должна улучшиться, так как вам не нужно создавать ресурс изображения каждый раз, когда тест на правду терпит неудачу.
$handlers = array( IMAGETYPE_GIF => 'imagecreatefromgif', IMAGETYPE_JPEG => 'imagecreatefromjpeg', IMAGETYPE_PNG => 'imagecreatefrompng' ); $type = exif_imagetype($img_temp); if(array_key_exists($type,$handlers)){ $proc_img = call_user_func_array($handlers[$type],array($img_temp)); } else { // do error logic here }
Другая добавленная выгода заключается в том, что вы можете добавлять обработчики, не создавая гигантский оператор if. См. http://www.php.net/manual/en/function.exif-imagetype.php для получения дополнительной информации.