Как организовать безопасную загрузку фото на сервер

Тема в разделе "PHP", создана пользователем verfaa, 4 ноя 2012.

Статус темы:
Закрыта.
Модераторы: latteo
  1. verfaa

    verfaa

    Регистр.:
    29 янв 2007
    Сообщения:
    375
    Симпатии:
    41
    Знаю, что в нете есть статьи на эту тему (к сожалению большинству из них уже 4-5 лет, возможно они уже не актуальны), но все же хотелось бы обсудить этот вопрос у нас на форуме.
    На сайте через форму загружаются фото. Нужно максимально, насколько это возможно обезопасить себя от попадания на сервер всякой гадости (шеллов и т.п.)
    Каким образом это сделать?
    Некоторые рекомендуют делать resize картинки. При resize файла изменяется содержимое файла — если скрипт, он просто не заработает, так как тоже подвергнется видоизменениям. Если функция resize выдаст ошибку — просто удаляем файл.
    Насколько этот метод хорош? Какие есть методы лучше? Какие ещё дополнительные проверки и условия вводить в скрипте-обработчике фото?
    На папку, в которую загружаются фото пришлось поставить 0777. Может дополнительно копировать в неё файл .htaccess, который запрещал бы выполнение любых файлов в этой папке? Как этот .htaccess в таком случае должен выглядеть?
    Вообщем поделитесь кто как защищает свои проекты.
    Судя по обилию рипов всевозможных сайтов эта тема очень актуальна...
     
  2. QuZ

    QuZ Постоялец

    Регистр.:
    18 июл 2009
    Сообщения:
    74
    Симпатии:
    49
    1) Перед загрузкой проверяйте размер и расширение файла.
    2) При созранении - сразу переименовывайте ее.
    3) Правильно насройте веб сервер. Картинки должен отдавать nginx или подобное.
    4) Права доступа на папку, куда заливать указать.
    5) Создаете уменьшенную копию изоображения, которую и будете выводить на сайте, для того, чтобы человек не знал ни название новое, н и место где хранится.

    Итого - ПХП даже не лезит к этим файлам, при их обращении фронтенд отдает их, а остальное - хоть и параноя, но не трудно сделать.
     
  3. RomkaLTU

    RomkaLTU Создатель

    Регистр.:
    28 окт 2012
    Сообщения:
    12
    Симпатии:
    7
    Вы также должны отключить PHP excecution в каталог images.
     
  4. drw36

    drw36 Создатель

    Регистр.:
    11 ноя 2012
    Сообщения:
    12
    Симпатии:
    2
    чем больше различных манипуляций с файлом, тем лучше. Это может быть не только ресайз, но и наложение (текста, эффекта, другой полупрозрачной картинки), изменение формата (jpg2png, или jpg2png2jpg; иметь ввиду: при конверте png2jpg или png2jpg2png могут теряться полутона, прозрачность оригинального png; в случае jpg2png2jpg оригинальный jpg вряд ли по качеству сильно изменится). Если с пхп будет беда (или на чём сайт?), ImageMagick в помощь (там можно сразу и ресайз, и конверт сделать).
    Вот только оправдывает ли цель средства...
     
  5. CNiks0N

    CNiks0N lamp.root

    Регистр.:
    28 ноя 2008
    Сообщения:
    230
    Симпатии:
    48
    Q_BASIC нравится это.
  6. mustang86

    mustang86 Писатель

    Регистр.:
    13 дек 2012
    Сообщения:
    8
    Симпатии:
    0
    1) Я использую функцию getimagesize() :
    http://php.net/manual/ru/function.getimagesize.php
    Она будет работать только, если это изображение.
    2) получить доступ ко всем изображений через скрипт .htaccess использованием phpThumb:
    http://phpthumb.sourceforge.net/
    Если файл загружен, и это не образ, это не будет доступна (например, PHP оболочки).
     
  7. mike1111

    mike1111 Создатель

    Регистр.:
    7 янв 2013
    Сообщения:
    18
    Симпатии:
    3
    Использую вместе с функцией getimagesize(), изменение имени файла,
    примерно так:
    Код:
    $ext = strrchr($_FILES['load']['name'], ".");
    $photo = date("YmdHis",time())."$ext";
    получается дата, но если много загружают сразу
    можно ограничить по времени sleep (1); ,
    что бы не пропадали файлы.
     
  8. ka291

    ka291 Писатель

    Регистр.:
    26 дек 2012
    Сообщения:
    1
    Симпатии:
    1
    Оригинал закаченной картинки ложить в папку с закрытым доступом через htaccess
    Resize картинки + для большей уверенности наложить watermark и если хоть в одном месте что-то не так - удалить.
    А если надо отдавать оригинал, то отдавать через PHP файлик,

    типа вот так:

    Код:
      $id=round($_GET['id']);
      $src="upload/$id.jpg";
      if(!file_exists($src)){
          $src="upload/0.jpg";
      }
      Header("Content-type: image/jpeg");
      $imgcode = implode('',file($src));
      echo $imgcode;
    
    в моём примере закрытая папка это upload
    если нет файла, то подгружаеться подготовленная заранее картинк 0.jpg
    при желании можно добавить и проверку на тип изображения и выдавать соответствующий заголовок
     
    verfaa нравится это.
  9. Mashonka

    Mashonka Создатель

    Регистр.:
    17 янв 2013
    Сообщения:
    32
    Симпатии:
    3
    Пользуйтесь на здоровье :)
    Если хостинг на линуксе:
    - для хранения файлов просто вынесите этот каталог за пределы www директории (выше директории т.е. чтобы из вэб он был недоступен), а если нету возможности такой, то назовите каталог именем которое не подберут (напр: userimagejf202-vm39dZa3f) или
    - при uploade проверяйте соответствие mime типа ожидаемому (php exif функциии) и если TRUE то сохраняйте в папку вне веб директории
    - для защиты контента раздавайте файлы создавая временные жесткие или мягкие ссылки (php link(), symlink() ) - вида [дата_оконч_действия].crc_random_name и кроном проходите раз в сутки и удаляйте устаревшие ссылки(инф: жесткая ссылка(имя файла) указывает непосредственно на индексный дескриптор, а мягкая указывает на жесткую ссылку т.е. на имя файла http://younglinux.info/bash/linktheory.php). Ни в коем случае на production сервере не отдавайте файлы средствами php.
    - мягкие ссылки ложить всегда в специальный каталог типа "http://site/yourtemplinks/" или каталоги симулирующие файловую структуру сайта "http://site/image/big/"
    - собственно также красиво можно отдавать и через ftp://
     
  10. unkn0wn

    unkn0wn

    Регистр.:
    22 дек 2006
    Сообщения:
    163
    Симпатии:
    86
    Проще всего при загрузке картинки использовать функцию http://php.net/getimagesize, если вместо массива вернет FALSE - можно гарантированно удалять файл. Этого более чем достаточно в 99.9% случаев, но если майор паранойя не дремлет по поводу уязвимости в реализации getimagesize, то до кучи можно отключить исполнение php в папке с картинками через .htaccess и при загрузке генерировать имя на основании того же md5 (ну или id пользователя, если грузится аватар, к примеру) и расширения из getimagesize. Больше ничего делать не требуется.

    Вариант, предложенный ka291 хорош лишь на сайтах с мизерной посещалкой, отдавать статику через php - зло.
     
    verfaa нравится это.
Статус темы:
Закрыта.