日本スマートフォンセキュリティ協会(JSSEC)が公開している『Androidアプリのセキュア設計・セキュアコーディングガイド』を読んだので、キーセンテンスをまとめておきます。各項目の詳細な解説はガイドにあります。
1. Activityを実装する際のルール
- アプリ内でのみ使用するActivityは非公開設定する
- taskAffinityを指定しない
- launchModeを指定しない
- Activityに送信するIntentにはFLAG_ACTIVITY_NEW_TASKを設定しない
- 受信Intentの安全性を確認する
- 独自定義Signature Permissionは、自社アプリが定義したことを確認して利用する
- 結果情報を返す場合には、返送先アプリからの結果情報漏洩に注意する
- 利用先Activityが固定できる場合は明示的IntentでActivityを利用する
- 利用先Activityからの戻りIntentの安全性を確認する
- 他社の特定アプリと連携する場合は利用先Activityを確認する
- 資産を二次的に提供する場合には、その資産の従来の保護水準を維持する
- センシティブな情報はできる限り送らない
2. Broadcastを送受信する際のルール
- アプリ内でのみ使用するBroadcast Receiverは非公開設定する
- 受信Intentの安全性を確認する
- 独自定義Signature Permissionは、自社アプリが定義したことを確認して利用する
- 結果情報を返す場合には、返送先アプリからの結果情報漏洩に注意する
- センシティブな情報をBroadcast送信する場合は、受信可能なReceiverを制限する
- Sticky Broadcastにはセンシティブな情報を含めない
- receiverPermissionパラメータの指定なしOrdered Broadcastは届かないことがあることに注意
- Broadcast Receiverからの返信データの安全性を確認する
- 資産を二次的に提供する場合には、その資産の従来の保護水準を維持する
3. Contect Providerを実装する際のルール
- Android 2.2(API Level 8)以前ではアプリ内でのみ使用するContent Providerは作らない
- アプリ内でのみ使用するContent Providerは非公開設定する
- リクエストパラメータの安全性を確認する
- 独自定義Signature Permissionは、自社アプリが定義したことを確認して利用する
- 結果情報を返す場合には、返送先アプリからの結果情報漏洩に注意する
- 資産を二次的に提供する場合には、その資産の従来の保護水準を維持する
4. Serviceを実装する際のルール
- アプリ内でのみ使用するServiceは非公開設定する
- 受信データの安全性を確認する
- 独自定義Signature Permissionは、自社アプリが定義したことを確認して利用する
- 連携するタイミングでServiceの機能を提供するかを判定する
- 結果情報を返す場合には、返送先アプリからの結果情報漏洩に注意する
- 利用先Serviceが固定できる場合は明示的IntentでServiceを利用する
- 他社の特定アプリと連携する場合は利用先Serviceを確認する
- 資産を二次的に提供する場合には、その資産の従来の保護水準を維持する
- センシティブな情報はできる限り送らない
5. SQLiteを使用する際のルール
- DBファイルの配置場所、アクセス件を正しく設定する
- 他アプリとDBデータを共有する場合はContentProviderでアクセス制御する
- DB操作時に可変パラメータを扱う場合はプレースホルダを使用する
6. ファイルを扱う際のルール
- ファイルは原則非公開ファイルとして作成する
- 他のアプリから読み書き権限でアクセス可能なファイルは作成しない
- SDカードなど外部記憶デバイスに格納するファイルの利用は必要最低限にする
- ファイルの生存期間を考慮してアプリの設計を行う
7. Browsable Intentを利用する際のルール
- (Webページ側)対応するリンクのパラメータにセンシティブな情報を含めない
- URLのパラメータを利用する前に値の安全性を確認する
8. LogCatにログを出力する際のルール
- 運用ログ情報にセンシティブな情報を含めない
- 開発ログ情報を出力するコードをリリースビルド時に自動削除する仕組みを導入する
- Throwableオブジェクトをログ出力するときはLog.d()/v()メソッドを使う
- ログ出力にはandroid.util.Logクラスのメソッドのみ使用する
9. WebViewを使用する際のルール
- JavaScriptを有効にするのはコンテンツを自社が管理している場合に限定する
- 自社管理サービスとの通信にはHTTPSを使用する
- Intent経由など、他から受け取ったURLはJavaScriptが有効なWebViewには表示しない
- SSL通信のエラーを適切にハンドリングする
10. パスワード入力画面を実装する際のルール
- パスワードを入力するときにはマスク表示(●で表示する)機能を用意する
- パスワードを平文表示するオプションを用意する
- Activity起動時はパスワードをマスク表示にする
- 前回入力したパスワードを表示する場合、ダミーパスワードを表示する
11. 独自Permissionを使用する際のルール
- AndroidOS規定のDangerousPermissionはユーザーの資産を保護するためにだけ利用する
- 独自定義のDangerous Permissionは利用してはならない
- 独自定義Signature PermissionはComponentの提供側アプリでのみ定義する
- 独自定義Signature Permissionは自社アプリにより定義されていることを確認する
- 独自定義のNormal Permissionは利用してはならない
- 独自定義のPermission名はアプリのパッケージ名を拡張した文字列にする
12. Authenticatorアプリを実装する際のルール
- Authenticatorを提供するServiceは非公開Serviceとする
- ログイン画面ActivityはAuthenticatorアプリで実装する
- ログイン画面Activityは公開Activityとして他のアプリからの攻撃アクセスを想定する
- KEY_INTENTには、ログイン画面Activityのクラス名を指定した明示的Intentを与える
- アカウント情報や認証トークンなどのセンシティブな情報はログ出力しない
- Account Managerにパスワードを保存しない
- Authenticatorとオンラインサービスとの通信はHTTPSで行う
- Authenticatorが正規のものであることを確認してからアカウント処理を実施する
13. HTTP通信、HTTPS通信をする際のルール
- センシティブな情報はHTTPS通信で送受信する
- HTTP通信では受信データの安全性を確認する
- SSLExceptionに対しユーザーに通知する等の適切な例外処理をする
- TrustManagerを変更しない、独自のTrustManagerを作らない
- HostnameVerifierを変更しない、独自のHostnameVerifierを作らない
14. プライバシー情報を扱う際のルール
- 送信する利用者情報は必要最低限に留める
- 初回起動時(アップデート時)に、ユーザーによる取り換えが困難、または、慎重な取り扱いが求められる利用者情報の送信について包括同意を得る
- 慎重な取り扱いが求められる利用者情報を送信する場合は、ユーザーに個別同意を得る
- ユーザーがアプリ・プライバシーポリシーを確認できる手段を用意する
- アプリ・プライバシーポリシー概要版をassetsフォルダ内に配置しておく
- 送信した利用者情報をユーザー操作により削除および送信停止する手段を用意する
- 端末固有IDとUUID/cookieを使い分ける
- 利用者情報を端末内のみで利用する場合、外部送信しない旨をユーザーに通知する
15. 暗号技術を利用する際のルール
- 暗号を指定する場合は、明示的に暗号モードとパディングを設定する
- アルゴリズム的に脆弱でないもの(基準を満たすもの)を使用する
- パスワードベース暗号のパスワードを端末内に保存しないこと
- パスワードから鍵を生成する場合は、Saltを使用する
- パスワードから鍵を生成する場合は、適正なハッシュの繰り返し回数を指定する
- パスワードの強度を高める工夫をする