今回はネイティブアプリケーション[1] 内のXSS(Cross-Site Scripting 、クロスサイトスクリプティング)脆弱性の傾向と対策について解説します。
ネイティブアプリの現状
内部にHTMLやJavaScriptを使って構築されるスマートフォン向け、デスクトップ向けのアプリケーションが増えています。その結果、今までWebサイト上で起きていたような問題が、ネイティブアプリケーション内でも起こるようになっています。アプリケーション内におけるJavaScriptコードのインジェクションは、クロス「サイト」ではないのでXSSと呼ぶのは適切ではありませんが、脆弱性の原因と対策方法はまさにWebサイトにおけるXSS脆弱性と同じです。
今回は、個人的に問題を発見・報告したことのある事例を挙げながら、「 脆弱性をどのように発見するか」「 どう修正すればよいのか」「 どうすれば未然に防げるのか」を考察します。
HTML+JavaScriptがアプリケーション実行環境として広く普及していく中、Webアプリケーションで繰り返されてきたようなJavaScriptに起因する脆弱性は、Webサイト以外でも多く見られるようになっています。特に端末のバリエーションが豊富なスマートフォン向けのアプリケーションにWebベースの技術が多く使われています。
通常、WebアプリケーションにXSS脆弱性があった場合、影響範囲は明確です。そのドメイン上で任意のJavaScriptが実行可能であり、深刻度はそのドメインが預っている情報[2] によって評価できます。
しかしWebベースの技術を用いたスマホ向けアプリケーションに脆弱性があった場合、サンドボックス[3] やパーミッションによって影響が軽減されるものもあれば、通常のWebアプリケーションでは起こりえないような、より深刻な問題を含むケースもあります。
ここではSkype for Mac、Skype for iOS、Sparrowの3例を取り上げます。
Skype for Macの事例
Skype [4] for Macの5.x系列には、チャットメッセージを経由することで、任意のJavaScriptコードを実行可能な脆弱性がありました。5.1.0.922未満が影響を受けます。筆者が報告したタイミングでは、すでに既知の問題として認識されており、しばらくしてhotfixがリリースされています。
この脆弱性を発見した当初は、単にスクリプトが実行される、チャット画面を壊すことができる、といった認識でいましたが、深堀りして調査していくうちに、深刻な問題であると気づきました。
Skypeのチャットメッセージの表示画面はローカルファイルとして表示されているのですが、ファイル名がアプリ側から既知で、実行中のユーザの権限で読み取り可能な任意のファイルを読み取り、リモートサーバに送信することが可能である、ということがわかったのです。また、チャットメッセージを削除してしまえば、相手にほとんど気づかれることなく実行することが可能です。この問題については同時期に報告していた人が多くいたようです。
この原因は、チャットメッセージ中のURL自動リンク処理にバグがあったことでした。
[4] 2011年にMicrosoftに買収された、インターネット電話・チャットサービスです。P2P技術を利用したものですが、Windows版以外にもLinux、Mac OS X、iPhone、iPod touch、iPad、Android、Nokia N800、PSP、PS Vita用のソフトウェアが無料で提供されています。
Skype for iOSの事例
iOS向けのSkypeにも以前、脆弱性がありました。ニックネーム部分にHTMLタグを含めることが可能であり、チャットメッセージ経由で相手のSkype上で任意のJavaScriptコードが実行可能になる、というものでした。実際にアドレス帳を盗み出すデモ動画が公開されたこともあり、話題になりました 。筆者は、Skype for iOSの脆弱性が報道されるまでは「アプリ内XSSによってiOSのアドレス帳を盗み出すことができる」ことを認識していませんでした。
Skype for iOSのチャットメッセージの表示には、UIWebViewというコンポーネントが使われており、これはHTMLで作られています。iOSにおけるアドレス帳のファイルは、/private/var/mobile/Library/AddressBook/ AddressBook.sqlitedb
に保存されています。このファイルをJavaScriptからXMLHttpRequestを使って読み取ることが可能になっていました。iOS 6以前は、アドレス帳と発着信履歴を保存しているファイルは、特に制限なく読み取ることができる状態でした。
Sparrowの事例
Mac OS X/iOS 用のメーラーであるSparrow にHTMLメール経由でローカルファイルを盗み出すことができる脆弱性がありました。
2012年7月9日に筆者はこの問題を伝え、OS X版に関しては修正版が1週間後の7月17日にリリースされ、iOS版は8月30日に修正されています 。現在すべてのバージョンにおいて、筆者の把握している範囲で脆弱性が修正されています[5] 。
[5] これとは別に、Sparrowの過去バージョンのメール表示部分には、メール本文とは別にFromヘッダ部分で送信者名にHTMLタグが含まれていた場合にタグが有効なまま表示されてしまうというバグがありました。これは筆者が報告する前から認識されていたようで、報告時の最新版ですでに修正されていました。
潜在する類似の問題
複数のプラットフォームで動作するアプリケーションにおいて、内部的にHTMLとJavaScriptが使われており、UIの構築やメッセージの表示に使われている事例は珍しくありません。そしてSkypeやSparrowのように、1つのプラットフォーム上で問題があれば、別のプラットフォーム上でも同様のバグが存在する、という事例は多く見られます。
共通点がいくつか見られるかと思います。内部でHTMLを使っていること、複数のプラットフォームで同様の問題があったこと、そして人気のアプリケーションであるにもかかわらず、Webアプリケーションにおいては典型的、初歩的とも言えるようなバグがつい最近まであった、ということです。
バグから脆弱性への昇格
HTMLを表示する処理がバグっていて、本来意図しないタグが使えてしまったり、スクリプトが実行できたとしても、常に危険なことができるわけではありません。適切に実装されている場合は、単にタグが使えたりスクリプトが実行できたとしても、危険なことができないようになっています。
ここでは脆弱性となり得る可能性のあるバグを潰すため、筆者が行っているネイティブアプリケーションのバグの見つけ方を紹介します。
Sparrowの調査過程
Sparrowを例に挙げると、バグ調査は次のような過程で行いました。
① 旧バージョンにおいてFromヘッダ経由で任意のHTMLタグが表示可能であることを把握する
② alertを使って情報取得を試みるが、表示されないことを確認する
③ ダイアログが抑制されているが、スクリプト実行自体は行われている可能性を考え、別の手段での情報取得を試みる
④ document.writeなどで画面内の要素を書き換え可能であることを確認する
⑤ new Image( ).srcや XMLHttpRequestで任意のURLへのリクエストが可能であることを確認する
⑥ 決め打ちのパスに置いたファイルの内容を取得して任意のURLに送信可能なことを確認する
⑥の段階で、Fromヘッダの表示部分とメール本文の表示部分が、同一のHTML内に表示されていることに気付きました。
Fromヘッダ経由でHTMLタグが混入する脆弱性については、調査時点での最新版ですでに修正されていましたが、この段階でリリースノートにはsecurity fixとして告知されている様子がありませんでした。
つまり、Fromヘッダ経由でHTMLタグが混入するというバグを認識して修正はされたけれども、セキュリティ上の問題だとは考えなかったのではないか、という不安がよぎったのです。JavaScript経由でローカルファイルを盗み出すという攻撃手法を知らなかったために、単なるバグだと考えてしまったのではないかと予想したわけです。
同一のHTML内にメール本文が含まれているということは、HTMLメールの表示処理にバグがあった場合には、同等の危険があることを意味します。ひょっとしたらHTMLメールの表示自体にも漏れがあるのではないか? と考えました。
HTMLサニタイジングの危険な側面
そこで、Fromヘッダの脆弱性を通じて、送信されたHTMLメールがどのように解釈されて、表示されるのかを検証することにしました。
すると、scriptタグやonload onerror onclickなど、典型的なスクリプトの実行方法がブロックされていることが確認できました。
一方、onhoge="xxx"
やonfuga="xxx"
といった、独自の属性については除去されていないことが確認できました。つまりon.*
といった条件で、on
で始まるすべての属性を除去しているならまだしも、ブラックリスト方式で既知のイベントハンドラしか除去していない、ということがこの時点で予測できます。
あとはブラックリストをくぐり抜けるタグと、スクリプトを実行可能な属性を見つければ、任意のスクリプトが実行可能であることがわかります。
Sparrowはブラックリスト方式でのHTMLサニタイジング処理[6] を行っていました。
しかし、ブラックリスト方式でのHTMLサニタイジングをセキュリティ上の理由で用いてはいけません。ブラックリスト方式のフィルタが有用であるケースは、ほとんどないと言えるでしょう。ブラックリスト方式のサニタイジング処理が危険は、開発者が知らないうちに、知らないタグや知らないイベントハンドラが追加される点です。レンダリングエンジンによっては独自のイベントハンドラがサポートされている場合もあります。そのアプリケーションをリリースした段階では危険なタグやイベントハンドラを網羅していたつもりでも、将来に渡って安全であると保証できません。
Sparrowのケースでは、audioタグやvideoタグなど、HTML5で新規に追加されたタグは素通しになっていました。また、onloadstartなどの新規に追加されたイベントハンドラが通るようになってしまっていました。