JSSECが公開している『Androidアプリのセキュア設計・セキュアコーディングガイド』の2016-09-01版を共有用にまとめているもののうち、「4.9. WebViewを使う」のものとなります。
詳細やサンプルコードについては原著の方を参考ください。
チェックポイント
- JavaScriptを有効にする場合、自社が管理しているコンテンツ以外にアクセスしない(※厳密な条件は後述)
- 自社管理サービスとの通信にはHTTPSを使用する
- Intent等、他から受け取ったURLはJavaScriptを有効にしない
- 有効にする必要がある場合は、事前にアプリ内でホワイトリストを持っておき、照合する
端末内のローカルコンテンツを表示する場合
- 端末内のコンテンツをWebViewで表示し、JavaScriptを有効にする場合、assetsとresディレクトリ以外へのアクセスを禁止する
インターネット上の自社管理コンテンツを表示する場合
- サービス側の用意するコンテンツは、自社の管理していないコンテンツを参照しない
- アプリ側はSSL通信エラーを適切にハンドリングする
- アプリ側は表示するURLをHTTPSプロトコルだけに限定する
- アプリ側は表示するURLを自社管理コンテンツだけに限定する
自社管理コンテンツ以外を表示する場合
- JavaScriptを有効にしない
- HTTPS通信の場合、SSL通信のエラーを適切にハンドリングする
Tips
JavaSctiptを有効にして良いタイミング
厳密には、安全性が保証できるコンテンツにアクセスする場合のみ、JavaScriptを有効にしても問題ありません。そのため、正確には、自社管理というより、自社以外が書き換え不可能なコンテンツにアクセスする場合になります
例えば、各コンテンツがサーバ内のみを参照かつ、適切なセキュリティ対策がされているならば問題ありません
また、apk内のassets等も他アプリから書き換え不可能なため、JavaScriptを有効にして問題ありません。外部記憶装置に配置されたコンテンツは書き換え可能なため、JavaScriptは無効にする必要があります
もし、JavaScriptを有効にし、自社以外が書き換え可能なコンテンツにアクセスする場合は、そのコンテンツに対する信頼性と、問題が起こった際の責任を考える必要があります
HTTP通信について
自社サービスに確実に接続するため、HTTPSを使用する必要があります
また、HTTPS通信でSSLエラーが発生した場合、エラーをユーザーに通知し、サービスとの通信を終了する必要があります
AndroidのWebViewにはSSLエラーを通知する仕組みがないため、通知部分に関しては、自前での実装が必要です。
Android4.2未満の脆弱性について
Android4.2未満ではaddJavascriptInterface()に起因する脆弱性があり、JavaScriptからJavaのリフレクションを用いて、任意のJavaメソッドが実行できる脆弱性があります
Android4.2以降では@JavascriptInterfaceが指定されたメソッドしか操作できないように対策がされたので、この脆弱性はありません
fileスキームに起因する問題について
WebViewをデフォルト設定で使用する場合、fileスキームを利用してアクセスすると、アプリがアクセス可能なすべてのファイルにアクセスすることができます
対策としては、JavaScriptを有効にしないことのほかに、Android4.1以降の場合は
- setAllowFileAccessFromFileURLs()
- setAllowUniversalAccessFromFileURLs()
を利用してfileスキームによるアクセスを禁止することが出来ます
Web Messaging利用時の送信先オリジン指定について
Android6.0以降はHTML5 Web Messagingを実現できます
実装の際に、postWebMessage()の第二引数にて、送信先オリジンを指定します
が、この引数にはワイルドカードの指定も可能であり、その場合、どのようなオリジンに対してもメッセージの送信が行われるため、何らかの被害に繋がる可能性があります
そのため、第二引数のオリジンは明示的に指定するべきです
参考
『Android アプリのセキュア設計・セキュアコーディングガイド』【2016年9月1日版】
https://www.jssec.org/dl/android_securecoding.pdf