4

私は現在、PHP で Imagick ライブラリを使用しており、Image Magick のサイズ変更機能を使用しています。減圧爆弾と 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);

ただし、ディスクとメモリの制限を設定した後、画像がこの制限に達した場合、セグメンテーション違反エラーだけが発生し、例外はスローされません。これでは、適切に処理することができません。

アップデート:

私が使用しているパッケージのバージョンは次のとおりです。

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
4

3 に答える 3

3

ImageMagick-6.9.0-1 から、「幅」と「高さ」のリソース制限が追加されました。コマンドラインから、「-limit width 32000」などを使用します。幅または高さが指定された制限を超える場合、ImageMagick の PNG デコーダーは画像を解凍せずに救済します。

PNG デコーダーは、幅または高さが制限を超える画像を解凍しようとしません。

「領域」リソースは、以前のバージョンの ImageMagick (および Imagick) で利用できます。ただし、PNG デコーダーは「領域」制限に基づいて画像を拒否しません (Danack のコメントを参照)。

6.9.0 より前のバージョンの ImageMagick では、幅と高さの制限は libpng に由来し、libpng のバージョンに依存します。現在の libpng バージョン (1.0.16 以降、1.2.6 以降、1.5.22 以降、および 1.6.17 以降) では、1,000,000 列と幅の制限が課されます。バージョン 1.2.0 から 1.2.5、1.5.0 から 1.5.23、および 1.6.0 から 1.6.16 では、制限は既定で 27 億の行と列でした。

Imagick で RESOURCETYPE_AREA を探します (参照したマニュアルに _WIDTH または _HEIGHT が表示されないため、Imagick またはそのマニュアルを更新する必要があります)。だから試してみてください

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

100MegaPixel 制限を設定します。願わくば、Imagick の将来のバージョンで RESOURCETYPE_WIDTH と RESOURCETYPE_HEIGHT がサポートされ、減圧爆弾の脆弱性に対するより良い解決策が提供されることを願っています。これらを現在のバージョンの IMagick で設定する方法については、Danack の回答を参照してください。

于 2015-07-21T21:10:09.450 に答える
1

私が得るのはセグメンテーション違反エラーだけで、例外はスローされません

あなたのセグメント障害は、ImageMagick (および関連するデリゲート) が動作するにはリソースの設定が低すぎることが原因であると推測しています。リソースの値はメガバイト単位ではなく、バイト単位です。

リソースに到達すると、 Imagick例外をスローします。通常、次のようなもの...

"キャッシュ リソースが不足しています"

減圧爆弾、またはZip-Bombsは、識別するのが非常に困難です。イメージを -ing し、リソース制限を設定することによって行うこと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)

解凍が信頼できない場合は、 ping 検証中に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 で作成) は、デフォルトのリソース制限と、アップロードされた画像に対してそれらをチェックする方法の良い出発点を提供します(を検索してPingください)。

于 2015-07-21T18:47:18.907 に答える