金利0無利息キャッシング – キャッシングできます

 | 

2014-01-10

AndroidのWebViewの脆弱性についての私的なまとめ

18:19 | AndroidのWebViewの脆弱性についての私的なまとめ - 金利0無利息キャッシング – キャッシングできます を含むブックマーク はてなブックマーク - AndroidのWebViewの脆弱性についての私的なまとめ - 金利0無利息キャッシング – キャッシングできます

http://jvn.jp/jp/JVN53768697/ についての私的なまとめです。業務時間中に調べた内容も含まれていますが、この記事はmala個人の文責で書かれています(所属している組織の見解ではありませんし、所属している組織やそのグループ会社からリリースしているアプリが必ずしもこの記事で書かれているような対策が取られているとは限りません)

  • 書きかけの部分があるので、あとで追記します。
  • Androidの開発を専門としていないので、何か問題があればツッコんでください、訂正します。

この脆弱性はつまるところなんなのか

  • 1. addJavascriptInterfaceが危険だというのは周知されていることだった
  • 2. reflection使って思ったより危険なことが出来てしまう
  • 3. 使って無ければ関係ないと思いきや、標準のWebViewクラスを使っているだけで勝手にaddJavascriptInterfaceが使われている

これまで、3についてパブリックな場所での言及が避けられてきましたように思います(少なくとも大々的にセキュリティ会社が警告を出したり、Googleが発表したりはしていない)

もっとも実際に検証コードを書けば、多くのアプリに脆弱性があることが容易に分かる状態でした。

自分の知る限り

  • このバグは、JVNで公表される前から、セキュリティ業界内では広く知られていた。
  • セキュリティ関係の会社や、Android端末を作っているベンダーは知っていた(知らなきゃおかしい)
  • ある程度大きな会社のセキュリティ関連の仕事をしてる人であれば多分知っている

という状態でした。にも関わらず、一番問題を知らなくてはいけないはずの、Androidアプリケーション開発者にこの問題が周知されてこなかったように思います。

結果として、

  • Android4.4.x でも依然として危険な addJavascriptInterfaceを使っているアプリ
  • Android3.0-4.12 で動作させた場合に危険な、WebViewを使っているアプリ

Google Play上に多数存在しています。一般的にはJVNで脆弱性情報が公開されるのは問題が解決した後なのですが、市場におけるAndroid OSのバージョンごとのシェアや、アップデート困難な端末、addJavascriptInterfaceを使ってしまっているアプリの数を考えると、多くの課題を残したまま公表されていると考えたほうが良いです。

問題箇所と修正箇所

リフレクションを使ってClassLoaderを呼び出して、といった話はこちらに書かれてるので省略します。

問題があったのは searchBoxJavaBridge_ というjsInterfaceです。Android 4.1.2まで存在していました。Googleがどういう対策を取ったかというと、addJavascriptInterfaceを使う際には @javascriptInterfaceアノテーションが使われているメソッドしか呼び出せないように制約を加えました。

暗黙のうちに使われていたaddJavascriptInterfaceについては、このコミットで

ごっそり削除されています。ちなみに勝手にaddJavascriptInterfaceが使われるコードが追加されたのはタブレット用にリリースされたAndroid3.0からで、ちょうどクローズドソースだった時期です。

JVNのベンダーの対応状況を見ると、4.2で修正されたという扱いになっているように見えますが、4.2.xでも設定次第で影響を受けます。具体的にはユーザー補助のTalkback機能を有効にするとaddJavascriptInterfaceが使われます。

開発者向けのドキュメント内での警告の遍歴

古くからaddJavascriptInterfaceの利用の際の注意は書かれていた。

2009年3月

「危険なAPIである」と、ごく初期からドキュメントに書かれているにも関わらず、Android3.0でどういうわけかその危険なAPIOS側で標準で使われている状態になってしまっていた。

2012年8月 reflectionについての記述が増える

2012年11月 API変更についての告知が出される

影響を受けるアプリ

  • 1. WebViewを使っていて、古いAndroidでも動作するようになっているもの
  • 2. 明示的にaddJavascriptInterfaceを使っていて、任意のURLを開けるアプリ(特にブラウザ)

1について、わざわざ古いAndroidで動かないようにしているアプリはそんなに無いと思います。つまりは、WebViewを使っているアプリ全般です。影響を受けないほうが珍しいと思います。もし「古いAndroidを使っているユーザーであっても保護したい」と考えるのであるならば、後述するような対策を取ったほうが良いことになります。

もちろん「OS側の問題なのでサポートしない」という判断をするのも、それはそれで間違っていないと思います。広く知られていないだけで古いバージョンには深刻な脆弱性が他にも含まれているのでしょうし、古いOSを動作対象に含め続けることは時として新しいOSへの移行を遅らせて、ユーザーをより危険な状態に晒すことにもつながります。Windows2000WindowsXPを延命させようとするようなものです。

アプリケーションの持っている権限によっては、アドレス帳を読み取ったり電話番号を読み取ったり、SMSを送信したり出来ます。多くのアプリケーションが未対策であっても、強い権限を持っているアプリの場合はリスクが大きくなるので対策したほうが良いという判断を取ることもありうるでしょう。

2について。著名なブラウザのいくつかがaddJavascriptInterfaceを使っています。多分すでに誰かが報告していたりするとは思いますが、おそらく「問題を認識してはいるが、重要な機能が依存していて外せない、古いAndroidで動作しないようにするという判断も取りづらい」という板挟みになっているのではないかと思います。

検証コード

OSのバージョン等の取得、Contextオブジェクト経由でアプリケーションの情報を取得、コマンド実行を行うものです。Android3.0 - 4.1.2でWebViewを使っているアプリやブラウザ、または明示的にaddJavascriptInterfaceを使っているアプリやブラウザで動作することが確認できると思います。2番目は「Android4.4 + addJavascriptInterfaceを使ってるアプリ」では動きません。

アプリ側で取れる対策について

一番単純なのは「Android最新版を使え、古いバージョンのAndroidを使ってるユーザーはどうなっても知らんよ」ということです。無責任かもしれませんが、何もしなくてよいです。古いバージョンのAndroidを使っているユーザーを保護したいのであれば以下のような対策を取る必要があるでしょう。

JavaScriptを無効にする

setJavaScriptEnabled(true) と明示的に指定しない限りJavaScriptはデフォルトで無効になっています。単にドキュメントを表示するだけでJavaScriptが有効である必要がないなら、JavaScriptを無効にしてしまいましょう。

開発元の提供するURLしか開かないようにする + 全てのアクティブコンテンツにHTTPSを使う

信用できるURLしか開かないようにします。その上で、ユーザーが信用出来ない回線を使っていて通信が改竄されるようなケースも考慮するのであれば、HTMLJSなどscriptを実行しうる全てのリソースのロードにHTTPSを使います。

removeJavascriptInterfaceで決め打ちで削除する
mWebView.removeJavascriptInterface("searchBoxJavaBridge_"); 

WebViewのonCreateのタイミングでsearchBoxJavaBridge_を削除することで、Webページ側からjsInterfaceが見えなくなることを確認しました。accessibilityも消したほうが良いかもしれません(エミュレータでTalkbackが使えなかったので未検証)

重要な機能がaddJavascriptInterfaceに依存している場合には?

代替手段を考える
  • WebViewとJavaの側で、相互にメッセージを送ることが出来れば、ブリッジ機能は作ることが出来ます。
  • バッドノウハウの類だとは思いますが、例えばalertダイアログを使ってメッセージのやりとりをするテクニックが紹介されています
  • http://qiita.com/ka_/items/f8dcde7893f3a029f151

Java → WebViewにはjavascript: なURLを開かせれば任意のJavaScriptコードを実行することが出来ますし、WebView → Javaも、Java側から監視可能な何らかの変更を行えばJavaに対してメッセージを送ることも出来ます。

責任の所在はどこにあるのか?

「addJavascriptInterfaceを使っていない」アプリに関して言えば、これはあくまでOS側のバグによる問題で、本来ならアプリ側で修正するような問題ではないでしょう(堅苦しく言えば、瑕疵担保責任が発生するようなものではないと考えている)

「addJavascriptInterfaceを明示的に使っている」アプリ(@javascriptInterfaceに移行してない)に関しては、アプリ側の脆弱性です。バグ報告しましょう。

具体的な攻撃方法に触れずに、かつ、互換性を壊さずに緩やかに新しいバージョンに移行するという観点からすれば、Googleの取った修正方法は適切だと思うし、十分に説明を行ってきているし、やるだけのことをやったとは言えるのだろう。

欲を言えば、

  • reflection使われたりClassLoader呼ばれたりしたら問答無用でエラーになるような仕組み作ったり出来ないのか?とか
  • Google Playのマルウェア検出の仕組み使ってWebView使ってるアプリ調査して作者に警告出したり出来ないのか?とか

思ったりはする。しかし、現状そうなってはいないし、将来的にそういった取り組みが行われるとしても今すぐに出来るとは思えないし、古いバージョンのAndroidは市場に一定数残る。つまり「放っておいても安全になる」ということは無い。もはや、OS側での修正はこれ以上期待できない状態だと思ったほうが良い。addJavascriptInterfaceを使っているアプリは、修正しない限り勝手に安全になったりはしないです。

ユーザー側で取れる対策について

「怪しいサイトを訪問しない」といったことがよく言われますが、怪しくないサイトのiframeに埋め込まれても攻撃は成立します。本気で悪人が攻撃しようとした場合は、広範なサイトに埋め込まれる広告やwidgetのiframeやjsを乗っ取ったり、全てのHTTP通信を透過プロキシで書き換える偽WiFiアクセスポイントを立てたりするでしょう。

アドホック対応の歴史

似たような事例として(あくまで自分がそう感じるだけだけど) ソフトウェア側での脆弱性の修正が行き届くまでに時間がかかるので、Webサイト側で問題を迂回するという対策が取られてきたことがある。

CSSXSS

2005年12月頃から知られ始めた、IE6HTMLCSSとして読み込ませてクロスドメインでのデータ漏洩を起こす脆弱性。

2006年6月の累積的なセキュリティ更新プログラムで修正された(その後も対策が不完全で修正されたりしている)

紛れも無くブラウザ側の問題なのだけれど、脆弱性があることが知られてから、ブラウザ側で修正が行われるまでの期間が長いので、実際に攻撃を受けたり影響を無視することが出来ないような意識の高いWebサイトは「出力されるHTMLCSSとして解釈される余地がないように」とか「異なる文字コードで解釈されても大丈夫なように」するための対策が行われてきた。

PDFXSS

2006年12月に報告、2007年1月に広く知られる

2006年12月にAdobe Reader8、2007年1月にAdobe Reader 7.0.9を公開されており、それぞれ問題が修正されている。

その上で(現実的に全てのユーザーが最新版を使っているとは限らないので)サーバー側での迂回策もAdobe自ら公表した。

雑多なこと

最初の報告者は誰?

IPAに届け出た人は http://tama-sand.blogspot.jp/2013/12/JVN53768697.html 2012年9月とのことだけれども、これ以前に、MBSDから報告されているとのこと。

おそらく複数の研究者から報告があったと思います。


Googleは自社の脆弱性情報について積極的に公開はしない?

Googleの考える再考された「責任ある開示」 ポリシーは

Googleはこれまで、「深刻な脆弱性は60日以内に修正すべきであり、それができない場合は情報を公開して一時的な回避策を提示すべき」との立場を取ってきた。”

“「7日という期限は一部メーカーにとっては短か過ぎて製品のアップデートは間に合わないかもしれないが、当面の回避策についてアドバイスを公開するだけの時間は十分にある」とGoogleは主張。この独自基準に従って、7日が経過してもメーカーが修正パッチや脆弱性情報を公開しない場合は、研究者による情報の公開を支援すると明言した。"

Androidのソースコードレベルでは、報告されてから60日以内に修正されているだろうし、その後のAPI設計の変更も適切だろうけれど、この問題はまさにOS側での修正が無理なら無理で、アプリケーション側での迂回や、ユーザー側での回避策(標準ブラウザを使わない、信用出来ないWiFiを使わない、等)が取れる状況であったのに、Googleからは脆弱性情報としては公表されなかった。

公表されることで攻撃される可能性が高まるのか、あるいは、個々のアプリ側の対策やユーザー側の自衛によってリスクが低くなるのか、どのタイミングでの公表が適切だったのか、ハッキリ言って全く分からない。わからないのだけれど、今となっては既に十分すぎるほど「公表されている」状態だと思うので、古いAndroidが市場に残っている以上は、アプリ開発者側での対策やユーザー側での自衛手段を周知していく必要があるんじゃないかと思う。(あるいは古いAndroidはサポート期限切れだから使うなと全力で広報する)

攻撃コードを隠すためのテクニックについて

OSSにおいて、セキュリティアドバイザリやコミットログから攻撃コードを推測しにくいようにするということが、ちょくちょく行われている。

実際にはセキュリティ上の理由での修正なのだけれど、リファクタリングや方針転換のように見せかけて、問題の原因となるファイルを丸ごと削除したり入れ替えたりする。あるいは、セキュリティ修正と機能追加を含む社内ブランチをまとめてマージして、修正箇所を分かりにくくするといったテクニックが使われたりする。

隠すことによるセキュリティの一種のように思えるのだけれど、diffの難読化のようなことが是非はともかく現実に行われている。

トラックバック - http://subtech.g.hatena.ne.jp/mala/20140110
 |