| SQLインジェクション対策はおすみですか? 開発開始時点からのコンサルティングから、公開済みWebサイトの脆弱性検査、 脆弱性発見後の適切な対策まで |
2007-08-07 mod_imagefight考
● 画像版サニタイズ言うな
しばらく前から、竹迫さんのイメージファイト(mod_imagefight)が、第10回セキュリティもみじセミナーなとで発表され話題になっていましたが、LL魂で発表されたプレゼン資料が公開されましたので、私もようやく内容を見させていただきました。
先日、PHPの攻撃コードが隠された画像ファイルが、大手ホスティングサイトで発見されたとの報道がなされました。GIF,PNG,JPEG,BMP形式の画像ファイルには、PHPのRFI攻撃で使用されるコードやJavaScriptのソースなどを埋め込むことができます。画像に埋め込まれた攻撃コードと戦う5つの方法について解説し、安全な画像アップローダの実装について考察します。
[TAKESAKO @ Yet another Cybozu Labs: LL魂お疲れ様でした[LLSpirit]より引用]
公開されただけで61枚のプレゼン資料、4分間のライトニングトークですからいつもながら大変なものです。おそらく会場はやんやの喝采だったことと推察します。
で、その中で提案されている mod_imagefight の手法ですが、画像によるXSSやRFI攻撃(Remote File Inclusion Attack)を防止するために、画像ファイル中に、PHPやJavaScriptを無効化するコード(テキスト)を挿入するものと理解しました。詳しくは、竹迫さんの素晴らしいプレゼン資料を参照ください。
攻撃を予防するためのコードは、以下のようなものだそうです(C言語ソース形式、行番号は徳丸が付与)。
1:static const char antixss[] =
2: "\"'*/-->-->]]>\n\n"
3: "<img src=# style=position:absolute;top:15;left:10;visibility:visible>"
4: "<style>body{font-size:0;visibility:hidden}"
5: "<plaintext style=display:none><?php die;?>";
つまり、<style>や<plaintext> (PHPについては<?php die;?>)を挿入することにより、後続の<script>などを無効化しようというたくらみですね。
これはサニタイジングと呼ばれる手法の一種と考えられ、竹迫さんのプレゼン資料でも、サニタイGIF(sanitigif)とかサニタイピング(sanitipng)という造語を使って説明されている。このあたりのセンスはサスガですね。その一方で、同じプレゼン資料には、サニタイズ org という言及もみられます。これの意味するところは(プレゼンを聞いていないので)分かりませんが、想像するに、以下のどちらかではないでしょうか。
- サニタイズという言葉を使うと某方面から批判が出る
- サニタイズという手法は本質的にアドホックなもので、対応に限界がある
ここでは後者について検討してみます。
サニタイズに使用しているコードを見ると、スタイル指定<style>により<script>を無効化するとともに、念のため<plaintext>を併用して、万一<style>に対する対策がなされても、<plaintext>により<script>を無効にしているように見えます。
しかし、この対策は、攻撃者側が</style>や</plaintext>を攻撃コードに含めることで対応できそうです。攻撃コードの例を以下に示します。
</plaintext></style><script>alert('xss');<script>
私の環境ではすぐには mod_imagefight を試せそうにないので、代わりに竹迫さんのサニタイズ用テキストと攻撃コードを並べた文字列を埋め込んだ画像を作成してみました。右の画像がそうで、IEで画像のリンクをクリックすると、画像が表示され、alertによるダイアログが表示されます。画像が表示される理由は、サニタイピング文字列の3行目に<IMG src=#>があるためですね。
えーっと、竹迫さんの実装では、サニタイピング文字列はコメント欄などを利用して埋め込むのだと思いますが、それは面倒だったので、全てパレットテーブルに押し込んでいます。本質的な差はないと思いますが、私の思い違いであればご指摘ください。
この画像の16進ダンプを以下に示します。ハイライトしている部分がパレットの先頭部分で、サニタイピング文字列+対抗文字列+XSS文字列の順に並んでいます。

というわけで、サニタイズという手法では、割合簡単に対抗策が取られてしまうのではないかという疑問を持ちました。
僕のオオボケであればご指摘ください。
テスト用に、サニタイピング文字列なしバージョンも用意しましたので、よろしければご利用ください。
さて、イメージファイトの改良についてですが、サニタイズ手法を使っている限り、攻撃者との「いたちごっこ」はつきまとうと思っています。画像のアップロード処理は、たとえばウィルスチェックが必要な場合もあるでしょうから元々重たい処理なのだと割り切って、もっと画像の中身をいじらないとしょうがないのではないかと思います。
しかし、どうしてもサニタイズ的アプローチでやりたいのであれば、現状の<style>や<plaintext>ではなく、以下のようにJavaScriptで別のURIに遷移してしまったらどうでしょうか?
<script>location.href="/";</script>なんか毒をもって毒を制す風情がありますね(^-^;
この方法のデメリットは、画像を直接(<IMG>を使わないで)表示できなくなることです。しかし、そういう応用は少ないのではないでしょうか?<IMG>による表示やダウンロードであれば問題ないと思います。
追記
kazuhooku さんからはてブコメントをいただきました。「plaintext の閉じタグサポートしてる実装はあるんだろうか」ということですが、確かに主要なブラウザは</plaintext>を実装していませんね。ケータイのブラウザなどは対応していますが、なにせ今はIE固有の話題をしているわけで、失礼しました。なんとなく、(本当は終タグが必要だという意識もあって)書いてしまいました。すなわち、</plaintext>は書いても書かなくても意味は同じで、本質的に<style>の中はCDATAなので<plaintext>書いても効力ないこと、<style>の方は終タグが書けるので、攻撃側対応が容易というところが問題でした。<plaintext>を前にもって来るべきでしたね。
まぁ、いずれにせよ私の結論は変わらなくて、こういうややこしいこともあるので、サニタイズ的な手法はあぶないなぁということです。
追記(2007/08/08)
作者のTAKESAKOさんから突っ込みをいただきました。<style>は、閉じていなかったとだけということで、XSS対策としては<plaintext>の方だということ。たしかに、プレゼン資料ではそうなっていたので、実装では<style>も足して「より強力に」したのかなぁと思ったのは私の勘違いでした。試したわけではありませんが、この修正版を破るのは困難だと思いますので、現実的な対策としてはmod_imagefightは有効だと思います。ただ、この手法が、画像ファイルのXSS対策の決定版になるかどうかは、もう少し検証が必要だと思いますので、引き続き検討したいと思います。
ありがとうございました。
LL魂の感想の続きで、竹迫良範さんのサニタイGIF↓凄いなあ、 TAKESAKO @ Yet another Cybozu Labs: LL魂お疲れ様でした[LLSpirit] みたいな事を書こうと思っていたら、あっさり破る方法が↓登場。 徳丸浩の日記 - mod_imagefight考 - 画像版サニタイズ言うな とり
mod_imagefightのBMP処理に対する攻撃方法を検討しました
- tDiary.Net ×1
- http://www.tokumaru.org/ ×223
- http://b.hatena.ne.jp/HiromitsuTakagi/ ×129
- http://labs.cybozu.co.jp/blog/takesako/2007/08/lls... ×85
- http://b.hatena.ne.jp/HiromitsuTakagi/20070812 ×40
- http://b.hatena.ne.jp/entry/http://www.tokumaru.or... ×32
- http://d.hatena.ne.jp/monjudoh/20070807/1186505259... ×31
- http://d.hatena.ne.jp/teracc/20070808 ×11
- http://b.hatena.ne.jp/entrylist?sort=hot&of=50&thr... ×10
- http://clip.nifty.com/entry/fd6be9504bfb8cb9a4d1be... ×10
- http://ab.wryy.net/ ×9
- http://d.hatena.ne.jp/teracc/20070715 ×7
- http://d.hatena.ne.jp/monjudoh/ ×6
- http://d.hatena.ne.jp/ockeghem/ ×6
- http://d.hatena.ne.jp/teracc/ ×5
- http://buzzurl.jp/entry/http://www.tokumaru.org/d/... ×5
- http://b.hatena.ne.jp/hotentry?cname=elec ×5
- http://www.saiyasuweb.com/ ×5
- http://d.hatena.ne.jp/butyricacid/ ×5
- http://b.hatena.ne.jp/entrylist?sort=hot&of=50&thr... ×5
- http://b.hatena.ne.jp/kazuhooku/ ×4
- http://b.hatena.ne.jp/entrylist?sort=hot&of=100&th... ×4
- http://1470.net/list/memo/recent/ ×3
- http://b.hatena.ne.jp/t/イメージファイト ×3
- http://a.hatena.ne.jp/harupu/ ×3
- http://b.hatena.ne.jp/ockeghem/ ×3
- http://www.saiyasuweb.com/3/c/テーブル ×3
- http://b.hatena.ne.jp/HiromitsuTakagi/?of=20 ×3
- http://www.tokumaru.org/d/20070807.html ×3
- http://d.hatena.ne.jp/keyword/LLSpirit ×3
- http://feed-tv.com/masui/play ×3
- http://b.hatena.ne.jp/mi1kman/favorite ×3
- http://www.tokumaru.org ×3
- http://r.hatena.ne.jp/NSR250R-SP/受信箱/ ×3
- http://a.hatena.ne.jp/ockeghem/ ×3
- http://a.hatena.ne.jp/mao140/ ×3
- http://bluedot.us/users/tsupo/dot/92504698000 ×3
- http://b.hatena.ne.jp/entry/http://labs.cybozu.co.... ×2
- http://b.hatena.ne.jp/mikihoshi/favorite ×2
- http://b.hatena.ne.jp/otsune/20070812 ×2
- http://b.hatena.ne.jp/otsune/ ×2
- http://clip.nifty.com/entry?url=http://www.tokumar... ×2
- http://d.hatena.ne.jp/ockeghem/?of=5 ×2
- http://www.math.sansu.org/u/diary/ ×2
- http://b.hatena.ne.jp/entrylist?sort=hot&of=150&th... ×2
- http://b.hatena.ne.jp/pero1/favorite ×2
- http://b.hatena.ne.jp/HiromitsuTakagi/?of=40 ×2
- http://b.hatena.ne.jp/entry/4703817 ×2
- http://b.hatena.ne.jp/TAKESAKO/イメージファイト/ ×2
- http://b.hatena.ne.jp/yuiseki/?word=javascript ×2
- http://b.hatena.ne.jp/entry/5504676 ×2
- http://b.hatena.ne.jp/Hamachiya2/?of=40 ×2
- http://b.hatena.ne.jp/keyword/サニタイズ ×2
- http://b.hatena.ne.jp/Kanatoko/ ×2
- http://b.hatena.ne.jp/entrylist?sort=hot&of=100&th... ×2
- http://bookmark.fc2.com/search/tag/xss ×2
- http://fastladder.com/subscribe/http://www.tokumar... ×2
- http://bloger.x0.com/result/buzz/buzz clip ×2
- http://b.hatena.ne.jp/HiromitsuTakagi/?of=80 ×2
- http://b.hatena.ne.jp/t/mod_imagefight ×2
- http://reader.livedoor.com/subscribe/http://www.to... ×2
- http://nihongo.homeip.net/word/サニタイズ/ ×2
- http://b.hatena.ne.jp/t/セルクマ ×2
- http://reader.livedoor.com/subscribe/http://www.to... ×2
- http://press.eek.jp/result/gif/gif 画像 ×1
- http://wafful.org/mod_imagefight/mod_imagefight.c ×1
- http://search.hatena.ne.jp/websearch?word=visibili... ×1
- http://press.eek.jp/result/アップローダー/画像アップローダー ×1
- http://erokey.ddo.jp/diary2/None/sixpence none the... ×1
- http://www.yahoogle.jp/redirect.php?url=http://www... ×1
- http://press.eek.jp/result/gif/gif ファイル ×1
- http://www16.learnjapan.org/kh/aHR0cDovL3d3dy50b2t... ×1
- http://reader.livedoor.com/subscribe/http://www.to... ×1
- http://tokumaru.org/ ×1
- http://www.tokumaru.org/index.htm ×1
- http://www.junk-search.com/tag/nsr250r.html ×1
- http://twitter.com/ockeghem?page=3 ×1
- http://www.jumperz.net/index.php?i=4&page=2&thread... ×1
- http://labs.ceek.jp/hbnews/ ×1
- http://faves.com/users/tsupo/tag/security/XSS ×1
- http://twitter.com/ockeghem ×1
- http://search.hatena.ne.jp/websearch?word=LL魂&page... ×1
- http://screenshot.hatena.ne.jp/0/5/7/3/c/1b3da1ba8... ×1
- http://nogue.cocolog-nifty.com/ ×1
- http://press.eek.jp/result/画像アップローダー/画像アップローダー ×1
- http://scuttle.cre.jp/ ×1
- http://press.eek.jp/result/ddo/ddo アップローダ ×1
- http://press.eek.jp/result/DDo/DDo ddo アップローダー ×1
- http://mmmemo.1470.net/mm/recent.html/url ×1
- http://mark.jolt.jp/pageDetail/61432 ×1
- http://pookmark.jp/user/tsupo/XSS ×1
- http://press.eek.jp/result/gif/gif イメージ ×1
- http://search.live.com/spresults.aspx?q=徳丸浩&go=検索&... ×1
- http://labs.ceek.jp/hbnews/list.cgi?c=1 ×1
- http://www.jumperz.net/index.php?i=4&page=1&thread... ×1
- http://r.hatena.ne.jp/katzchang/50.みんなのブクマ/ ×1
- http://tags.blogpeople.net/tag/RFI ×1
- http://labs.ceek.jp/hbnews/list.cgi?p=1&c=0 ×1
- http://rss.callbee.com//feed2js.php?src=http://tag... ×1
- http://search.www.infoseek.co.jp/Seek?svx=460402&n... ×1
- http://tags.blogpeople.net/ ×1
- mod_imagefight ×210 / 徳丸浩 ×11 / RFI攻撃 ×9 / サニタイズ言うな ×9 / mod_imageFight ×8 / キーワード不明 ×8 / サニタイズ ×6 / mod_ImageFight ×6 / 徳丸 画像XSS ×4 / png 動画 ×4 / XSS攻撃 16進数 ×3 / php 画像 xss ×3 / 画像 script 攻撃 ×3 / RFI攻撃 やってみた ×3 / PHP 画像XSS ×3 / 画像 スクリプト 埋め込まれた alert ×3 / sanitigif ×3 / 画像 XSS ×3 / Javascript テスト ×2 / IEEE754 浮動小数点数 ×2 / ウェブアプリケーションセキュリティ ×2 / C言語 16進ダンプ プログラム ×2 / mod_imagefight, ×2 / RFI XSS ×2 / fizzbuzz ×2 / CSRF waf ×2 / 画像日記 ×2 / php 画像 攻撃 例 ×2 / php 文字 画像 ×2 / visible hidden 画像 ×2 / img src jpeg xss ×2 / Remote File Inclusion Attack ×2 / gif サニタイズ php ×2 / 脆弱性 画像 script ×2 / <?PHP 画像XSS ×2 / 画像 サニタイズ ×2 / ruby サニタイズ ×1 / xss javascript ×1 / xss style script ×1 / XSS GIF ×1 / 画像ファイルにスクリプト 埋め込む 方法 竹迫 ×1 / SQLインジェクション やり方 ×1 / php 16進ダンプ ×1 / php die ×1 / style xss ×1 / 鵜飼昌樹 ×1 / php 画像 日記 ×1 / 画像の中身 ×1 / サニタイズ ファイル 無効化 ×1 / IEEE754 範囲 ×1 / plaintext 画像 脆弱性 ×1 / XSS対策 サニタイズ ×1 / 画像ファイル サニタイジング ×1 / font サニタイズ ×1 / xss アップローダ 画像 ×1 / remote file inclusion gif ×1 / php sql サニ ×1 / sql サニタイズ ×1 / IE 画像 XSS ×1 / サニタイズ 資料 ×1 / 徳丸 web ×1 / 画像 javascript xss ×1 / web db 総集編 ×1 / テスト画像 ×1 / 画像ファイル サニタイズ ×1 / xss style ×1 / サニタイズ xss ×1 / <> コード サニタイズ ×1 / 画像版 ×1 / XSS 版 ×1 / ウェブアプリケーションセキュリティ 金床 ×1 / 文殊堂 画像 ×1 / gif xss ×1 / 閉じタグ クロスサイトスクリプティング ×1 / gif 画像版 ×1 / HTML タグ サニタイズ ×1 / HTML サニタイズ ×1 / 画像 xss php ×1 / IEEE754 ×1 / タイピング文字 タグ 応用 ×1 / php hidden 攻撃コード ×1 / web アプリケーション 完全対策 ×1 / sql 型変換 ×1 / テキスト サニタイズ ×1 / tdiary html_anchor ×1 / 徳丸 浩 ×1 / セキュリティ サニタイズ alert ×1 / XSS 攻撃方法 画像 ×1 / Ruby サニタイズ ×1 / 簡単 タイピング文字タグ ×1 / 徳丸浩の日記 ×1 / 画像 gif script挿入 php ×1 / php 画像 文字 ×1 / 画像 アップロード サニタイズ ×1 / 整数の範囲 ×1 / php ファイル サニタイズ ×1 / 暗黙の型変換 インデックス ×1 / HTML JAVA サニタイズ ×1 / サニタイジング <script> ×1 / XSS style script ×1
| SQLインジェクション対策はおすみですか? 開発開始時点からのコンサルティングから、公開済みWebサイトの脆弱性検査、 脆弱性発見後の適切な対策まで |
元の防御コードの中でstyleの閉じタグが抜けていましたね。こちらのミス。
- 4: "<style>body{font-size:0;visibility:hidden}"
+ 4: "<style>body{font-size:0;visibility:hidden}</style>"
この修正で大丈夫だと思います。ご指摘ありがとうございました。