Snorway
@Snorway

Как обезопасить загрузку изображений на сайт?

Есть ли best practice по защите сайта от взлома через заливку шелла в изображении? Из известных мне - resize изображения. Надежно ли это?
  • Вопрос задан
  • 262 просмотра
Решения вопроса 1
Vamp
@Vamp
Суть уязвимости в том, что в метаданные картинки вставляется произвольный php код. Далее, используя уязвимости сайта, злоумышленник заставляет сервер исполнить эту картинку как php скрипт.

Чтобы избавиться от внедрённых таким образом шеллов, применяют ресайз, в ходе которого все метаданные теряются. Дополнительным бонусом идёт проверка валидности - imagecreatefromstring() и прочие аналогичные функции вернут ошибку, если пользователь залил битый/неподдерживаемый формат или вообще не картинку.

В принципе - это годный способ, если вам не нужен оригинал загруженного изображения. Используйте его без опасений.

Если оригинал всё же нужен, то следует удалить метаданные во время загрузки. Здесь уже будет посложнее, так как у каждого формата свои особенности в этом плане. Например, у jpeg это секции COM и APP1 (EXIF). У png - tEXt, iTXt и zTXt. У других форматов ещё какие-то свои особенности. То есть нужно разбираться в форматах изображений и использовать библиотеки, позволяющие работать с форматом на таком низком уровне. Причём надо удалять все метаданные, не относящиеся непосредственно к изображению, так как php код могут засунуть и в нестандартный чанк - браузер его проигнорирует и покажет картинку корректно, но php код там всё-таки присутствовать будет.

Можно ещё попробовать сделать поиск подстроки <? в сыром контенте файла. Если подстрока найдена, то, возможно, там есть какой-то php код. Способ так себе и не рекомендуется к применению - будет много ложноположительных срабатываний.

И ещё никогда не сохраняйте изображение в файловой системе под тем именем, с которым пользователь его загрузил. Генерируйте свои имена файлам. Если пользовательское имя файла нужно - сохраните его отдельно в базе.
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы