最近、ある開発案件の都合でImageMgickと格闘する時間が長い。
そんな中、この本を見つけたので読んでみた。
ImageMagickのリファレンスとしては貴重
ImageMagickを使用してみるとわかるのだが、オプションの数やバリエーションの豊富さに、ちょっとひいてしまう。
画像の処理をコマンドラインで行うという目的上、このオプションの多さは仕方のないことなのだが、意外とネット上にきちんとまとまった情報が少ない。(特に日本語で!!)
だから、何時間もかけて、ありとあらゆるパラメータの組み合わせを試したりしていたので、この本はとても役に立った。
しかーし!!
PHPのサンプルプログラムはダメです。
だけど、おや?
PHPによるサンプルプログラムがあると書いてある。
ImageMagickはPHPでは拡張モジュールなので、それに関するサンプルもあるのか?とおもって、中身をよく見るといくつか???と思う点があった。
- 拡張モジュールに関する記述はいっさいなし
- すべてsystem()関数で外部コマンドとしてコールしている
- そもそも、これらの12種類のサンプルのうち11種類はGD関数でできる。
つまりですね、PHPのサンプルはほとんどいらないってことです。
逆にここのサンプルを本番で使ってはダメではないのかな?
たしかに、PHPの過去のバージョンでは、Jpegの画質が荒いなどGD関数が使えない時代もあった、だからImageMagickのお世話になったこともある。
だけど、今はそんなことは無い。
すくなくとも、ネイティブに実装されている関数を使わないでsystem()で外部コマンドを呼び出すのは極力やめたほうがいい。
せめて、「GDでも同じことができるよん、そのほうが安全だよ」ぐらいのことは書いてあるべきだと思う。
少なくともうちのスタッフがこれをやったら、説教部屋行きはまちがいない。
外部コマンドは必ず絶対パスで指定すべし!!
さらに!!
この本で紹介されているプログラムにはいくつかの懸念がある。
まず第一に、外部コマンドの呼び出しに対して、絶対パス指定をしていない。
つまり、
exec(‘convert …..’);
としている。
これは、非常に気になる。
やはり、/usr/bin/convertのように絶対パスで指定しないと環境変数PATHを見に行ってしまい、セキュリティ上の懸念が生じてしまう。
ちなみに、Perlの汚染チェックモードでこれをやったら、致命的エラーがでる。
コマンドへの引数がエスケープされていない
たとえば、以下のようなコードが普通に書かれている。
$cmd = “convert “.$effop.” image/org_”.$fname.” image/”.$fname;
exec($cmd);
つまり、コマンドへの引数にエスケープが施されていない。
これは、パッと見ればセキュリティホールを抱えているように見える。
そこで、ソースをさかのぼると、うん確かに引数に使われている変数にはユーザーからの入力や環境変数は使われていない。
だから、安全?
いやいや、そうではない。
こうやってソースをさかのぼって見ないといけない時点で、問題ありなのです。
$cmd = "convert ".escapeshellarg($effop)." image/org_".escapeshellarg($fname)." image/".escapeshellarg($fname); exec($cmd);
とすれば一目瞭然、よけいな心配をする必要もなかったりする。
system()を使った際の万が一の時のダメージは、致命的である。
実際に、この本で紹介されているソースを見て安全であることを確信するには、わたしにはそれなりの時間が必要で、そう確信するまでにはいたらなかった。
それなら、いっそのことエスケープしてしまえというのが妥当な選択だと思う。
他にも!!
各サンプルの設計が悪いというかなんというか。。。
ほとんどのサンプルが、ひとつのPHPプログラムの中で、ImageMagickコマンドの発行、img要素(HTMLそのもの)の出力を行っている。
画像出力用のPHPとHTML出力用のPHPはわけたほうがよかったのではないかな?と思う。
実用上はそう考える方が圧倒的に多いような気がする。
というわけで
ImageMagickのコマンドリファレンスとしては、使うことも多いと思うのだが、PHPのサンプルは全く使えない。
GD関数でできることはGDでやるべきだし、外部コマンドを使いまくっている割に、そのリスクや注意点が全く書かれていない。
初心者の皆さんはこの本のPHPのサンプルは、くれぐれもあてにしないように。
少なくとも、このサンプルをあてにして買う価値はない!と思った。