こんにちは。マネージド&セキュリティサービス部セキュリティサービス部門の閏間です。総合リスクマネジメントサービス「WideAngle」の新サービスの企画を担当しています。 本記事では、私がセキュリティの知識・技術向上のために業務外で取り組んでいるバグバウンティプログラムについて、3回にわたって紹介します。 本記事により、バグバウンティプログラムの有効性と、脆弱性探しのおもしろさの両方を伝えられれば幸いです。
- (前編)バグバウンティプログラムの有効性について
- (中編)脆弱性探しの魅力と調査方法について
- (後編)実際に発見した脆弱性の詳細について【本記事】
なお、バグバウンティに関する記事としては、NTT Com社内バグバウンティのご紹介もありますので、ぜひそちらもご覧ください。
脆弱性の実例:3つの問題が重なってXSS(Cross Site Scripting)が発生
本記事では、私が過去に発見した脆弱性を1つ、技術的な詳細も含めてご紹介します(公開についてはアプリケーションの開発元に承諾を得ています)。
あるWebアプリケーションに、ユーザーのプロフィール画像を設定するという機能がありました。ここに以下の3つの問題があり、これらの問題が重なってXSSの脆弱性が発生していました。
- プロフィール画像のURLに直接アクセスすると、画像ファイルがダウンロードされるのではなく、直接Webブラウザー上で表示される。
- プロフィール画像を設定する際に指定した
Content-Type
の値が、プロフィール画像にアクセスした際のレスポンスにそのまま設定される。 - プロフィール画像を設定する際、画像以外のデータを設定でき、さらに、XSSフィルタ機能はあるものの、回避する手段がある。
XSSとは、Webページにスクリプトなどを埋め込むことができてしまう脆弱性です。悪用されるとWebページを閲覧しているユーザーの情報漏洩などにつながることもある、危険な脆弱性です。
1について
Webサイトにアクセスしたとき、Webサーバーから送り返されたコンテンツがWebブラウザー上で表示されるか、それともダウンロードされてファイルとして保存されるかは、Webサーバーからのレスポンスに含まれるContent-Disposition
ヘッダで決まります。以下のようにattachment
という値が付いていれば、Webブラウザーはコンテンツをファイルとして保存しようとしますが、付いていなければWebブラウザー上に表示します。
Content-Disposition: attachment
当該アプリケーションでは、プロフィール画像のURLに直接アクセスすると、レスポンスのContent-Disposition
ヘッダにattachment
は付いておらず、Webブラウザー上に画像が表示されました。ここで私は、「もしプロフィール画像として<script>タグを含むHTMLを保存でき、かつ、そのコンテンツがHTMLであるとWebブラウザーに認識させられれば、XSSを起こせるな」と考えました。
2について
画像ファイルにアクセスした場合、そのレスポンスのContent-Type
ヘッダには、画像コンテンツのファイル形式を示す値が設定される挙動が正しい動作です。例えば、jpeg画像の場合は以下のようになることが期待されます。
Content-Type: image/jpeg
しかし当該アプリケーションでは、プロフィール画像を設定する際に自動的に設定されるContent-Type
の値をローカルプロキシーツールで書き換えると、その後その画像ファイルにアクセスした際のレスポンスに書き換え後の値がそのまま使用されるという動きをしていました。プロフィール画像として設定するデータの中身が実際には何であっても、です。例えば、プロフィール画像の設定時にContent-Type
の値をtext/html
に書き換えると、画像ファイルのURLにアクセスした際、Content-Type
の値がtext/html
であるレスポンスが返ってきていました。
これで、「1について」に書いた「そのコンテンツがHTMLであるとWebブラウザーに認識させられれば」という条件を満たせることになります。残る壁は、いかにして「<script>タグを含むHTMLを保存するか」です。
3について
プロフィール画像を設定する際、データとして単純に<script>alert("XSS!!")</script>
のような文字列を渡しただけでは、エラーとなってしまって<script>タグを埋め込むことはできませんでした。どうやら、<
や>
があったらエラーにするというXSSフィルタ機能がWebサーバー側に備わっていたようです。
そこでこのXSSフィルタを突破すべく、以下の文字列をWebサーバーに渡しました。
+/v8-+ADw-script+AD4-alert("XSS!!")+ADw-/script+AD4-
これはエラーにならずに、プロフィール画像のデータとして保存されました。
そしてプロフィール画像のURLにアクセスすると、<script>タグが動作し、「XSS!!」と書かれたダイアログが表示されました。これでXSSの成立です。
ここで、なぜ<script>タグが動作したが疑問に思われた方もおられると思います。その原理は以下の通りです。
このXSSはInternet Explorer 11でのみ発動するのですが、以下のような流れでXSSが発動していました。
+/v8
は、UTF-7のBOM(Byte Order Mark; 符号化の種類の判別に使用する数バイトのデータ)である。- Internet Explorer 11は、UTF-7のBOMがコンテンツの先頭にあると、エンコーディングがUTF-7であるとみなしてコンテンツを表示する。
- エンコーディングがUTF-7の場合、
+ADw-
、+AD4-
はそれぞれ<
、>
を表すので、+/v8-+ADw-script+AD4-alert("XSS!!")+ADw-/script+AD4-
は<script>alert("XSS!!")</script>
と解釈され、スクリプトが実行される。
※XSSフィルタの突破方法については、Browser's XSS Filter Bypass Cheat Sheetを参考にさせていただきました。
本事例で紹介した脆弱性の要因はそれほど一般的なものではないため、作りこみ防止や検出方法はパターン化されていません。そのため、セキュア開発ライフサイクル活動や脆弱性診断をどんなに丁寧に行っても、このような脆弱性が運用フェーズに流出するリスクは残ると思います。そのようなリスクを少しでも0に近づけるために、バグバウンティプログラムは有効であると考えています。もちろん、脆弱性が運用フェーズに流出してしまったあとの検出手段としても、バグバウンティプログラムは有効です。
まとめ
バグバウンティプログラムの有効性と脆弱性探しの魅力について、3回にわたってご紹介しました。
ソフトウェアやシステムの開発・運用に携わる人の中には、セキュリティを専門に扱っていなくとも、脆弱性を発見できるだけの知識やスキルを持った方は大勢いると思います。そのような人たちも巻き込んでバグバウンティプログラムが発展を続け、世の中のシステム全体がよりセキュアな方向に向かえば素晴らしいことだと思います。
その一方で、ソフトウェアの脆弱性はセキュリティインシデントの原因の一部に過ぎないので、たとえ脆弱性がなくなっても、それだけでセキュリティに関するリスクが完全になくなるということはありません。ソフトウェアの脆弱性とは関係のない、人間の不注意を突くような攻撃や、組織内部の人物が行う不正行為によっても被害は発生し得るからです。 そのような事態に備え、防御、検知、対応、復旧といった活動をスムーズに行える体制づくりとその運用は、ソフトウェアの安全性がどんなに高まったとしても重要であり続けると考えています。