2010/02/23
■[CakePHP] mediaプラグインのGIFAR対策
Mediaプラグインは、アップロードファイルしたファイルそのもの(transfer/以下)への直接アクセス表示を非推奨として、代わりにfilter/以下に出力したVersionファイルの表示を推奨しています。
特に画像ファイル等に、セキュリティ上の理由があるためだそうですが、その例として上げられていた、「GIFAR」について、Versionファイル作成で対策になっているのか検証しました。
どうやらVersionファイル化することで、画像のGIFAR対策はOKのようです (^^)
直接アクセスした場合の問題
transferディレクトリへのアクセスを禁止する理由は、こちらの「4.」を参考にしました。
具体例として、以下の2つが挙げられています。
内容: IEのMIME Sniffing - てきとうなメモ
こちらは、Versionファイル作成の際、mineTypeチェック行なっているので対策になるのだろうと納得*1。
- GIFAR
こちらが初耳でした。
GIFARって何?
調べてみると、ユーザにファイルアップロードさせるのが怖くなります。。。
セキュリティ・ウォッチ - GIFを隠れ蓑に悪性Javaを勝手に実行:ITpro
現代ハッカーの基本テクニック - JARを利用した攻撃手法「GIFAR」【後編】 | ScanNetSecurity (特集、特集のニュース)
アップロードした画像表示だけでは問題ないのに・・・というあたりがイヤらしい (>_<)
上記、2番目と3番目の記事に、再現方法が記載してあったので、これらを参考にして検証してみました。
GIFAR画像の作成
まず、jarファイルを用意します。
HelloWorldを出力するだけの、ごく単純なjarです。
[cake@cake webroot]$ java -jar hello.jar Hello World
このhello.jarを、GIF画像と繋ぎ合わせてGIFARを作ります。
[cake@cake webroot]$ cat Image3.gif hello.jar > gifarImage3.gif
これだけです。
これだけで、ファイル種類を調べると、元の画像と同じGIF。
[cake@cake webroot]$ file hello.jar hello.jar: Zip archive data, at least v2.0 to extract [cake@cake webroot]$ file Image3.gif Image3.gif: GIF image data, version 89a, 100 x 100 [cake@cake webroot]$ file gifarImage3.gif gifarImage3.gif: GIF image data, version 89a, 100 x 100
でも、Javaとして実行可能なGIFARファイルのできあがり・・・
[cake@cake webroot]$ java -jar gifarImage3.gif Hello World
GIFARファイルをアップロード
このGIFARファイルをmediaプラグインでアップロードすると、一見なんの変哲もないGIF画像としてアップロードされました。
transfer以下の画像は、GIFファイルなのに、Javaとして実行可能なままで保管されていました。
[cake@cake webroot]$ file media/transfer/img/4b8395a6-2714-42a2-83aa-0a8bc0a80b08.gif media/transfer/img/4b8395a6-2714-42a2-83aa-0a8bc0a80b08.gif: GIF image data, version 89a, 100 x 100 [cake@cake webroot]$ java -jar media/transfer/img/4b8395a6-2714-42a2-83aa-0a8bc0a80b08.gif Hello World
では、filter以下に出力された画像は・・・?
[cake@cake webroot]$ file media/filter/m/transfer/img/4b8395a6-2714-42a2-83aa-0a8bc0a80b08.gif media/filter/m/transfer/img/4b8395a6-2714-42a2-83aa-0a8bc0a80b08.gif: GIF image data, version 87a, 100 x 100 [cake@cake webroot]$ java -jar media/filter/m/transfer/img/4b8395a6-2714-42a2-83aa-0a8bc0a80b08.gif Invalid or corrupt jarfile media/filter/m/transfer/img/4b8395a6-2714-42a2-83aa-0a8bc0a80b08.gif
みごと、Java実行エラーになりました!!
ブラウザ上でも、画像表示に問題ありませんでした。
その他、JPEG, PNGでも試して見ましたが、どちらも結果はGIFと同様でした。
[cake@cake webroot]$ cat Image1.jpg hello.jar > gifarImage1.jpg [cake@cake webroot]$ java -jar gifarImage1.jpg Hello World [cake@cake webroot]$ java -jar media/transfer/img/4b839846-a0e0-4c76-a671-0a8dc0a80b08.jpg Hello World [cake@cake webroot]$ java -jar media/filter/m/transfer/img/4b839846-a0e0-4c76-a671-0a8dc0a80b08.jpg Invalid or corrupt jarfile media/filter/m/transfer/img/4b839846-a0e0-4c76-a671-0a8dc0a80b08.jpg [cake@cake webroot]$ cat Image2.png hello.jar > gifarImage2.png [cake@cake webroot]$ java -jar gifarImage2.png Hello World [cake@cake webroot]$ java -jar media/transfer/img/4b8398c3-226c-4175-9e63-0a8ac0a80b08.png Hello World [cake@cake webroot]$ java -jar media/filter/m/transfer/img/4b8398c3-226c-4175-9e63-0a8ac0a80b08.png Invalid or corrupt jarfile media/filter/m/transfer/img/4b8398c3-226c-4175-9e63-0a8ac0a80b08.png
結論
主要な画像ファイル(JPEG, GIF, PNG)に関しては、MediaプラグインでVersionファイルを作成し、それを表示すべし、です。
■[CakePHP] mediaプラグイン応用(9) 元のファイル形式を保持して縮小
mediaプラグインでVersionファイルは、core.phpなどでconvertに設定した形式で出力されます。
元のファイル形式ままで出力する設定を追加しました。
注:この記事は、Viewで呼び出し時にVersionファイルを作成する 改修済みのソースをベースに記載しています。
MediaプラグインにファイルのmimeTypeを判別するライブラリが同梱されているので、それを使います。
使い方は、Mediaビヘイビアの357〜372行目付近を参考に。
app/plugins/media/libs/upfile.php
@@ -4,6 +4,7 @@
*/
App::import('Core', 'Shell');
+App::import('Vendor', 'Media.MimeType');
@@ -38,8 +39,16 @@ class Upfile extends Object {
// mimeType設定
if (isset($options['mime_type']) && !empty($options['mime_type'])) {
+ if ($options['mime_type'] == 'original') {
+ $File = new File(MEDIA. $orig_filepath);
+ if (!$File->readable()) {
+ return false;
+ }
+ $options['mime_type'] = MimeType::guessType($File->pwd());
+ }
$filter[$dir]['convert'] = $options['mime_type'];
}
Configure::write('Media.filter.'. strtolower($name), array($dir => $filter[$dir]));
以上で、core.phpなどに'convert' => 'original'を指定すれば、元ファイルのmimeTypeと同じ形式でVersionファイルが出力されます。
■[CakePHP] mediaプラグイン応用(8) VersionファイルのmimeTypeを任意で出力
Mediaプラグインの「Versionファイル機能」で出力される縮小画像の、ファイルタイプを任意に選べる改修を追加しました。
注:この記事は、Viewで呼び出し時にVersionファイルを作成する 改修済みのソースをベースに記載しています。
mimeTypeの設定
VersionファイルのmimeTypeを変更するには、convert設定を適宜変更します。
例
Configure::write('Media.filter.image', array(
- 'xxs' => array('convert' => 'image/png', 'fitCrop' => array(16, 16)),
+ 'xxs' => array('convert' => 'image/jpeg', 'fitCrop' => array(16, 16)),
core.phpやbootstra.phpで設定すると、全ての画像のxxsサイズ縮小ファイルが jpg 固定になります。
mimtType適宜指定したい場合は、例えば以下の様に改修します(引用ソースの委細は こちら 参照)
- Versionファイル出力時、$options['mimeType']の指定がある場合、convert設定を$options['mimeType']で上書き。
app/plugins/media/libs/upfile.php(Versionファイル出力ライブラリ)
/* Versionファイルの個別作成 */
function make_version($path, $orig_filepath, $options=array())
{
(中略)
// Confirgureの設定
$name = Medium::name($orig_filepath);
$filters = Configure::read('Media.filter.'. strtolower($name));
if (!isset($filters[$dir])) {
return false;
}
- Configure::write('Media.filter.'. strtolower($name), array($dir => $filters[$dir]));
+ $filter[$dir] = $filters[$dir];
+ // mimeType設定
+ if (isset($options['mime_type']) && !empty($options['mime_type'])) {
+ $filter[$dir]['convert'] = $options['mime_type'];
+ }
+ Configure::write('Media.filter.'. strtolower($name), array($dir => $filter[$dir]));
// Versionファイル出力
$Media->setup($Model);
$result = $Media->make($Model, $orig_filepath);
- 上記関数を呼び出す箇所で、適宜$options['mime_type']を設定。
app/plugins/media/views/elements/medium_edit.ctp(改修Attachmentエレメント)
$file = $upfile->file(
'filter/'.$previewVersion,
$item,
array(
'model_name' => $model,
+ 'mime_type' => 'image/jpeg',
)
);
■[ツール][メモ] 手軽にお試しZen-Coding
HTMLとCSSのコーディングを高速に行なえるプラグイン、「Zen-Coding」なるものが話題になっています。
TextMate+Zen-Codingで超速コーディング? | gaspanik weblog
使っているエディタがZen-Codingに対応していない場合、
あるいはプラグインの追加の手間をかけずに機能を試してみたい場合。
ブラウザだけで、Zen-Codingの主要機能を使える「Zen Coding for textarea」が配布されているので、これを試してみると良いかと思います。
Zen-Codingのデモ動画を見て、まず「これは凄い」と思いました。
HTMLおよびCSSのDOM指定ベースで変換するので、jQueryに馴染んだ身としては、取っ掛かり易そうでもあります。
しかし。
このZen-Codingは主にMacOnlyエディタのプラグインであり、
Windows版でフリーで試せるものも、情報は主にEclipse系のみ。
知らない人は損してる?コーディングが3倍速くなるZen-Codingを導入してみた - EC studio デザインブログ
そして私は、個人的にEclipseがあまり好きではないため、微妙に気乗りしません・・・
また正直、今CakePHPメインでやっていると、ヘルパー使うからメリットがどのくらいあるかと考えると、微妙でもあります。
探してみたら、ブラウザ上でZen-Codingの一部機能を使える「Zen Coding for textarea v0.6」というものがあったので、ひとまずこれで使い勝手を試してみることにしました。
http://code.google.com/p/zen-coding/downloads/list
- 「Zen Coding for textarea v0.6」ダウンロード&解凍
- example.htmlをブラウザで開き、
- TEXTAREA内にZen-condingで変換したいコードを記入。
- [Ctrl+適宜キー](DOM→タグ変換ならCtrl+E)
でZen-Codingの主要機能を使えます*2
テキストエリアの下にある、「Powered by Zen Coding」という青いボタンを押すと、どのショートカットキーを使えばよいか、簡易ヘルプも表示されます(英語ですが)
しばらくこれでZen-Codingの変換機能→エディタにコピペ で使ってみて、エディタで直接使いたいくらいに思ってきたら、正式にプラグイン導入検討しようと思います。
