3

В настоящее время я использую библиотеку Imagick на PHP и использую функциональность изменения размера Image Magick. Я только что узнал о декомпрессионных бомбах и о том, как ImageMagick уязвим для этого.Как предотвратить изображение бомб с помощью ImageMagick?

Я проверил, как мы можем выполнить ping изображение и проверить размеры изображения, не загружая его в память/диск. Также безопаснее ограничивать пределы памяти и диска ImageMagick, чтобы он не просто писал огромный файл на диске.

Я читал, и я могу сделать это с помощью setResourceLimit(). http://php.net/manual/en/imagick.setresourcelimit.php

IMagick::setResourceLimit(IMagick::RESOURCETYPE_MEMORY , 100); 
IMagick::setResourceLimit(IMagick::RESOURCETYPE_DISK , 100); 

$thumb = new Imagick('image.png'); 
$thumb->resizeImage(320,240,Imagick::FILTER_LANCZOS,1); 

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

Update:

Вот версии пакетов я использую:

dpkg -l | grep magick 
ii imagemagick-common     8:6.6.9.7-5ubuntu3.3    image manipulation programs -- infrastructure 
ii libmagickcore4      8:6.6.9.7-5ubuntu3.3    low-level image manipulation library 
ii libmagickwand4      8:6.6.9.7-5ubuntu3.3    image manipulation library 
ii php5-imagick       3.1.0~rc1-1      ImageMagick module for php5 
+0

Открытый вопрос: может ли быть какой-то низкоуровневый код, который может сканировать блоки сжатия и/или размер изображения до вызова ImageMagick? – halfer

ответ

5

Установка предела «Ресурсная область» устанавливает только размер, в котором изображения не хранятся в памяти, а вместо этого выгружаются на диск. Если вы хотите использовать этот параметр для фактического ограничения изображения максимального размера, которое может быть открыто, вам также необходимо установить ограничение «Resource Disk».

Правильный код, приведенный ниже, дает ошибку выделения памяти для взятых ими изображений. from here.

try { 
    Imagick::setResourceLimit(Imagick::RESOURCETYPE_AREA, 2000 * 2000); 
    Imagick::setResourceLimit(Imagick::RESOURCETYPE_DISK, 2000 * 2000); 

    $imagick = new Imagick("./picture-100M-6000x6000.png"); 
    $imagick->modulateImage(100, 50, 120); 
    $imagick->writeImage("./output.png"); 

    echo "Complete"; 
} 
catch(\Exception $e) { 
    echo "Exception: ".$e->getMessage()."\n"; 
} 

Выход:

Исключение: ошибка выделения памяти `./picture-100M-6000x6000.png» @ ошибка/png.c/MagickPNGErrorHandler/1630

Если вы хотите установить ресурс ширины и высоты и иметь версию ImageMagick> = 6.9.0-1, вы должны иметь возможность использовать значения непосредственно из WidthResource = 9, HeightResource = 10

//Set max image width of 2000 
Imagick::setResourceLimit(9, 2000); 
//Set max image height of 1000 
Imagick::setResourceLimit(10, 1000); 

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

Это делает невозможным правильное обращение с ним.

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

Лично я думаю, что в любом случае использование Imagick на сервере, к которому напрямую обращаются веб-браузеры, - это орехи. Гораздо безопаснее запускать его в качестве фоновой задачи (управляется чем-то вроде http://supervisord.org/) и обмениваться данными с этой фоновой задачей через очередь заданий, которые необходимо обработать.

Это не только позволяет решить проблему с «плохими изображениями», но и облегчает мониторинг использования ресурсов или переносит обработку изображений на машину с более быстрым процессором, чем на веб-интерфейс сервер.

Источника - Я сопровождающее расширение Imagick и я недавно добавил это риое Imagick:

Security

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

Поскольку ImageMagick используется для обработки изображений, возможно, для хакеров для создания изображений, содержащих недопустимые данные, чтобы попытаться использовать . В связи с этим мы рекомендуем следующее:

1) Не запускайте Imagick на сервере, который напрямую доступен из вне сети. Лучше либо использовать его как задачу , используя что-то вроде SupervisorD, либо запустить его на отдельном сервере , который не имеет прямого доступа в Интернете.

Выполнение этого будет затруднено для хакеров использовать ошибку, даже , если она существует в библиотеках, которые использует ImageMagick.

2) Запустите его как очень низкоприоритетный процесс. В максимально возможной степени должны быть заблокированы файлы и системные ресурсы , доступные для PHP-скрипта, из которого вызывается Imagick .

3) Проверьте, является ли результат обработки изображения действительным файлом изображения перед его отображением пользователю. В крайне маловероятном случае, что хакер способен передавать произвольные файлы на вывод Imagick, , проверяя, что это файл изображения, а не исходный код вашего отправляемого приложения , является разумной мерой предосторожности.

+0

Благодарим за обновление файла README! – emcconville

+0

Я обновил вопрос с версиями пакетов, которые я использую. Это странно, когда я использую imagemagick 8: 6.7.7.10-6ubuntu3 и php5-imagick 3.1.2-1build1, он правильно выбрасывает исключения. Тем не менее, я использую ubuntu 12.04 на сервере, и я не уверен, как я могу установить конкретные/обновленные версии imagemagick и php5-imagick. – maru

+0

Во всяком случае, звучит как отдельный вопрос. Это самый полезный ответ для меня. Спасибо за предложения! – maru

1

все, что я получаю ошибка ошибки сегментации, никаких исключений не выбрасывается

Я Предполагая, что ваш сегментный недостаток связан с ресурсами, слишком низкими для работы ImageMagick (и соответствующих делегатов). Значение ресурса находится в байтах, а не в мегабайтах.

Imagick делает исключение, если ресурс достигнут. Обычно что-то вроде ...

"Ресурс кэш исчерпал"

декомпрессионных бомбы или Zip-Bombs, чрезвычайно трудно определить. То, что вы делаете по ping, - это изображение, а также ограничение ресурсов - правильный курс действий. Я бы примерно очертить решение, как ...

// Define limits in application settings, or bootstrap (not dynamically!) 
define('MY_MAGICK_MEMORY_LIMIT', 5e+8); 
// Repeat for AREA, DISK, & etc. 

// In application 
$image = new Imagick(); // allocate IM structrues 
// Set limits on instance 
$image->setResourceLimit(Imagick::RESOURCETYPE_MEMORY, MY_MEMORY_LIMIT); 
// Repeat for RESOURCETYPE_AREA, RESOURCETYPE_DISK, & etc. 

$filename = 'input.png'; 
if($image->ping($filename)) { 
    // Validate that this image is what your expecting 
    // ... 
    try { 
     $image->read($filename); // <-- Bomb will explode here 
     $image->resizeImage(320,240,Imagick::FILTER_LANCZOS,1); 
    } catch(ImageickException $err) { 
     // Handle error 
    } 
} 
unset($image) 

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

typedef enum 
{ 
    UndefinedCompression, 
    B44ACompression, 
    B44Compression, 
    BZipCompression, 
    DXT1Compression, 
    DXT3Compression, 
    DXT5Compression, 
    FaxCompression, 
    Group4Compression, 
    JBIG1Compression, 
    JBIG2Compression, 
    JPEG2000Compression, 
    JPEGCompression, 
    LosslessJPEGCompression, 
    LZMACompression, 
    LZWCompression, 
    NoCompression, 
    PizCompression, 
    Pxr24Compression, 
    RLECompression, 
    ZipCompression, 
    ZipSCompression 
} CompressionType; 

MagickStudio (написанный в PERL) предлагает хорошую отправную точку для default resource limits, и как они checked against загруженных изображений (поиск по Ping.)

+0

Основываясь на документе, ограничение ресурса находится в мегабайтах. Я пробовал разные номера (100, 100000 и т. Д.), Но все равно получаю segfault. Я не получаю «ресурс кэша исчерпан», используя мой точный скрипт выше, просто segfaults (core dumped), что бессмысленно, потому что я думал, что для этого является setResourceLimit(). – maru

3

Начиная с ImageMagick-6.9.0-1, были добавлены ограничения на доступность "ширина" и "высота" . Из командной строки используйте «-граничную ширину 32000» и т. Д. Преобразователь PNG ImageMagick выйдет без декомпрессии изображения, если ширина или высота превысят указанный предел.

PNG-декодер не будет пытаться распаковывать изображения, ширина или высота которых превышает пределы.

Ресурс «Площадь» доступен в более ранних версиях ImageMagick (и Imagick); однако PNG-декодер не отклоняет изображения, основанные на пределе «площади» (см. комментарий Данака).

В версиях ImageMagick раньше чем 6.9.0 пределы ширины и высоты исходят от libpng и зависят от версии libpng. Текущие версии libpng (1.0.16 и более поздние версии, 1.2.6 и более поздние версии, 1.5.22 и более поздние и 1.6.17 и более поздние) налагают ограничения в 1000 000 столбцов и ширины. В версиях с 1.2.0 по 1.2.5, 1.5.0 - 1.5.23 и 1.6.0 - 1.6.16, ограничения по умолчанию составляли 2.7 миллиарда строк и столбцов.

Ищите RESOURCETYPE_AREA в Imagick (я не вижу _WIDTH или _HEIGHT в руководстве, на которое вы ссылались, поэтому необходимо обновить Imagick или его руководство). Поэтому попробуйте

IMagick::setResourceLimit(IMagick::RESOURCETYPE_AREA , 100M); 

установить предел в 100 мегапикселей. Надеемся, что некоторые будущие версии Imagick будут поддерживать RESOURCETYPE_WIDTH и RESOURCETYPE_HEIGHT, чтобы обеспечить лучшее решение для уязвимости, связанной с декомпрессионной бомбой. См. Ответ Danack о настройке их с текущей версией IMagick.

+0

Ресурс области является единственным подходящим параметром. ImageMagick не имеет отдельного ресурса для ширины/высоты https://github.com/ImageMagick/ImageMagick/blob/ImageMagick-6/magick/resource_.h#L27-L38 – Danack

+0

@ Danack Они представляют собой «WidthResource» и «HeightResource», в перечислении ResourceType. –

+0

Doh! Спасибо, я смотрел на старую версию локально .... – Danack

Смежные вопросы