Безопасное обслуживание изображений - PullRequest
12 голосов
/ 31 января 2011

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

Вместо этого он рекомендует хранить изображения над корнем и обслуживать их, используя fread или fputthrough.

Я не могу понять, каковы будут риски или почему они будут устранены при обслуживании через сценарий.
Накладные расходы такого сценария звучат смешно.

Я понимаю, что изображения должны быть проверены перед сохранением на сервере, и с этой целью я использую imagemagick для незначительного преобразования и сохранения в jpeg - что должно избавить от любого окалины, насколько я догадываюсь.

Итак, вопросы к великим умам на SO:

  1. Существуют ли какие-либо проблемы безопасности при локальном хранении изображений с легкими для отслеживания путями?
  2. Безопасен ли мой метод проверки изображений с помощью IM?
  3. Есть ли причина использовать PHP для обслуживания изображений?
  4. Действительно ли накладные расходы на использование PHP действительно существенны?
  5. Будет ли использование CDN иметь значение для безопасности (я не хочу)?
  6. Я что-то упустил?

Спасибо всем!

Ответы [ 4 ]

9 голосов
/ 31 января 2011

Я подозреваю, что ваш друг имеет в виду не просто отображение изображений, а, в частности, предоставление пользовательских изображений.Существует ряд проблем безопасности при обслуживании предоставленного пользователем контента.В случае изображений существует несколько способов использовать загрузку изображений, чтобы заставить веб-сервер выполнять код.Вот некоторые из наиболее известных:

  • Файл "GIFAR".По сути, это GIF-файл и JAR-файл, объединенный.Поскольку информация индекса для GIF находится в начале, а информация для файла JAR - в конце, два типа файлов можно объединить, и в результате получится как действительный GIF, так и действительный JAR.
  • Несколько файловрасширения.Веб-серверы поддерживают несколько расширений файлов, чтобы обеспечить такие вещи, как интернационализация.Например, файл с именем page.html.fr может отображаться на версию страницы на французском языке.Файл с расширением image.php.jpg или даже image.php.123 может быть выполнен в виде скрипта PHP, в зависимости от конфигурации сервера.
  • Переполнение буфера.Форматы файлов изображений обычно содержат заголовок в начале, который описывает размер и формат файла.Недооценка размера может позволить злоумышленникам создать атаку переполнения буфера.

Все эти примеры приводят к возможности выполнения кода в качестве веб-сервера.Хотя функциональность сайта требует возможности загружать файлы, хранение их в каталогах, которые не доступны напрямую по URL, затрудняет их использование.Точно так же использование сценария для их обслуживания, а не обработчиков MIME веб-сервера гарантирует, что изображения обрабатываются как поток данных, а не как потенциально исполняемый файл.пользователей, характер собранных данных о них и тривиальность веб-сайта.По крайней мере, злоумышленник хотел бы получить пароли пользователей из-за тенденции их синхронизации.Пользователь на вашем сайте, чей пароль ABC123, вероятно, будет использовать этот же пароль для электронной почты, социальных сайтов и возможных банковских и финансовых сайтов.Помимо паролей, если данные, которые вы собираете о своих пользователях, могут быть идентифицированы лично или имеют другую рыночную стоимость, или если у вас просто большое количество пользователей, то вы должны предположить, что сайт будет целью.Это означает, что вы должны быть более внимательны при обслуживании предоставленных пользователем файлов изображений, правильно их проверять или и того, и другого.

У меня нет точного ответа на вопрос, поможет ли использование imagemagick решить проблемы безопасности.По крайней мере, обязательно используйте текущую версию, потому что быстрый поиск обнаружил ряд известных уязвимостей.Помните, что файлы, о которых вам нужно беспокоиться, могут взорвать imagemagick, даже если они не используют одну из известных уязвимостей, поэтому убедитесь в том, что ДЕЙСТВИТЕЛЬНО хорошо перехватывает ошибки.

7 голосов
/ 31 января 2011

Если изображения не являются частными, то есть вы можете видеть их достаточно легко, вы просто не хотите, чтобы кто-то прочитал их все по своему желанию, может быть достаточно присвоить каждому уникальное имя.

Если их более нескольких тысяч (и это кажется вероятным), то создание иерархии каталогов, в которой они хранятся, также может помочь ускорить доступ, при этом увеличив пространство поиска настолько, что их не будет найденопри случайном поиске.Например: файл с именем 347168a5d9b4ac5eb386e396f68b2231.jpg может быть помещен в каталог: /images/34/71/68/347168a5d9b4ac5eb386e396f68b2231.jpg Многоуровневый каталог ускоряет доступ, избегая тысяч записей каталога из сканируемых случайных имен ихранится в базе данных, прикрепленной к списку изображений пользователя в галерее) останавливает поиск случайных файлов.

5 голосов
/ 31 января 2011

Заголовок такого сценария звучит смешно.

То же самое и здесь.Если изображения общедоступны, я не вижу абсолютно никаких причин для этого.

Если они не общедоступны (то есть должны быть доступны только зарегистрированным пользователям), то естьникак не обойти, как описывает ваш коллега (или использовать X-Sendfile после проверки входа в систему, что экономит часть издержек, если установлено необходимое программное обеспечение).Но если это не так, накладные расходы, необходимые для этого, составляют crazy .

0 голосов
/ 31 января 2011

Если вы определили, что на самом деле вам нужны изображения для обеспечения безопасности, то вот что я использовал в комическом проекте (в основном я помещаю тонны комиксов в каталог, а затем, когда наступит время, я позволю доступ к ним по одному)

//check if image should be accessed by the current request...

$fh=fopen($my_image,"rb");

if($fh==NULL){
        exit();
}
rewind($fh);
header("Content-Type: image/png");
header("Content-Length: " . filesize($fn));
fpassthru($fh);

fclose($fh);
exit();
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...