Безопасная загрузка изображения на сервер 


Безопасная загрузка изображения на сервер

Опубликовано

Безопасная загрузка изображения на сервер

Загрузка изображения должна проходить строгий контроль безопасности, в ином случае, не уделив должного внимания этой проблеме, вы можете создать серьезную “дыру”, через которую злоумышленник получит полный контроль над вашим сервером.

Далее приведен пример реализации безопасной загрузки изображения на сервер

1. Защита формы от подмены. С помощью суперглобального массива $_SERVER["HTTP_REFERER"] и прошивки формы сессией. Подробнее.

2. Обработка принятого изображения

 

Форма:

<form name="upload" enctype="multipart/form-data" action="upload.php" method="post">
  <input type="hidden" name="MAX_FILE_SIZE" value="102400" />
  <input type="file" name="uploadimg" />
  <input type="submit" name="Submit">
</form>

Метод передачи данных выбран POST, тип enctype="multipart/form-data". В скрытом элементе <input type="hidden" name="MAX_FILE_SIZE" value="102400" />, вы можете указать максимально допустимый размер изображения для загрузки в байтах:

 

PHP скрипт:

Проверка на подтверждение с помощью функции getimagesize(), что загруженный файл, на самом деле изображение.

$imageinfo = getimagesize($_FILES["uploadimg"]["tmp_name"]);
if($imageinfo["mime"] != "image/gif" && $imageinfo["mime"] != "image/jpeg" && $imageinfo["mime"] != "image/png") {
  print "Загруженный файл не является изображением";die;
}

Сохранение загруженного изображения с расширением, которое возвращает функция getimagesize()

//Расширение изображения
$mime=explode("/",$imageinfo["mime"]);
//Имя файла
$namefile=explode(".",$_FILES["uploadimg"]["name"]);
//Полный путь к директории
$uploaddir = "Z:/home/localhost/www/scripts/upload/";
//Функция, перемещает файл из временной, в указанную вами папку
if (move_uploaded_file($_FILES["uploadimg"]["tmp_name"], $uploaddir.$namefile[0].".".$mime[1])) {
  print "Изображение успешно загружено";
}else{
  print "Произошла ошибка";
}

Даже если злоумышленник обойдет все элементы защиты и вместо изображения загрузит файл с вредоносным кодом, то за счет того, что вы сохраните файл явно указав его расширение, он не сможет запустить его, т.к. PHP интерпретатор будет считать данный файл изображением.

 

Полный код:

<?php
if ($_POST["Submit"]){
  //Проверка, действительно ли загруженный файл является изображением
  $imageinfo = getimagesize($_FILES["uploadimg"]["tmp_name"]);
  if($imageinfo["mime"] != "image/gif" && $imageinfo["mime"] != "image/jpeg" && $imageinfo["mime"] !="image/png") {
  print "Загруженный файл не является изображением";die;
  }

  //Сохранение загруженного изображения с расширением, которое возвращает функция getimagesize()
  //Расширение изображения
  $mime=explode("/",$imageinfo["mime"]);
  //Имя файла
  $namefile=explode(".",$_FILES["uploadimg"]["name"]);
  //Полный путь к директории
  $uploaddir = "Z:/home/localhost/www/scripts/upload/";
  //Функция, перемещает файл из временной, в указанную вами папку
  if (move_uploaded_file($_FILES["uploadimg"]["tmp_name"], $uploaddir.$namefile[0].".".$mime[1])) {
    print "Изображение успешно загружено";
  }else{
    print "Произошла ошибка";
  }
}
?>
<form name="upload" enctype="multipart/form-data" action="upload.php" method="post">
  <input type="hidden" name="MAX_FILE_SIZE" value="102400" />
  <input type="file" name="uploadimg" />
  <input type="submit" name="Submit">
</form>

 

Подведем итоги:

Чтобы безопасно загрузить файл на сервер необходимо:

1. Защитить форму от подмены с помощью HTTP_REFERER и прошивки сессией

2. Проверить с помощью функции getimagesize() является ли загруженный файл изображением, а затем сохранить его, явно указав расширение файла.