JSSECが公開している『Androidアプリのセキュア設計・セキュアコーディングガイド』の2016-09-01版を共有用にまとめているもののうち、「4.2.Broadcast を受信する・送信する」のものとなります
詳細やサンプルコードについては原著の方を参考ください
チェックポイント
- 適切な公開範囲になっている
- 受信側は受信Intentの安全性の確認をしている
- 送信側は結果データの安全性の確認をしている
非公開Broadcast
- 受信側
- 静的Broadcast Receiverで構成されている
- 原則、Intent Filterを設置していない(例外については後述)
- exported="false"により、明示的に非公開にしている
- 送信側
- Stickyを使用していない(使用できない)
- 明示的IntentでBroadcastを送信する
公開Broadcast
- 受信側
- exported="true"を明示的に指定している
- センシティブな情報を返送していない
- 送信側
- センシティブな情報を送信していない
自社限定Broadcast
- 受信側
- Broadcast 受信用の独自定義Signature Permissionを定義している
- 結果受信用の独自定義Signature Permissionを利用宣言している
- exported="true"により、明示的に公開設定している
- 静的Broadcast Receiverを利用する場合、定義にて、独自定義Signature Permissionを要求宣言している
- 動的Broadcast Receiverを利用する場合、登録するとき、独自定義Signature Permissionを要求宣言している
- 独自定義Signature Permissionが自社アプリにより定義されていることを確認している
- Broadcast 送信元アプリと同じ開発者鍵でAPK を署名している
- 送信側
- 結果受信用の独自定義Signature Permissionを定義している
- Broadcast受信用の独自定義Signature Permissionを利用宣言している
- 独自定義Signature Permission が自社アプリにより定義されていることを確認している
- Receiver に独自定義Signature Permissionを要求している
- Receiver側アプリと同じ開発者鍵でAPKを署名している
Tips
Broadcast Receiverの定義方法
Broadcast Receiverには、2種類存在します
- 静的Broadcast Receiverはxml上に記述して定義します。ただし、システムから送信される一部のBroadcastを受信出きません。受信期間としては、アプリ初回起動から、アンインストールまでの間になります。(Android3.1以降。また、送信側がIntent.FLAG_INCLUDE_STOPPED_PACKAGESを設定した場合は1度も起動していなくても受信可能です)
- 動的Broadcast Receiverはプログラム中に記述して登録します。静的Broadcast Receiverでは受信できないものも受信でき、また、受信期間を制御できます。ただし、非公開にはできません
センシティブな情報の送信
センシティブな情報の送信をする場合、適切な送信方法を取らないと、不特定多数に一斉送信されるため、注意が必要です
- 明示的Intentで送信することで宛先を固定する方法
- 独自定義Signature Permissionを指定してBroadcast送信し、受信側Broadcast Receiverに利用宣言してもらう方法
Sticky Broadcast、Sticky Ordered Broadcastに関して
Android5.0から非推奨、また、悪名高い(らしい)ので、使用をしないのが良いです。もし、使用する場合はセンシティブな情報を含めてはいけません。明示的Intentを使用する、receiverPermissionパラメータを指定することが出来ないため、不特定多数から読み取れてしまいます
Ordered Broaccastに関して
Ordered Broadcastを使用する場合、receiverPermissionパラメータを指定せずにセンシティブな情報を送信してはいけません。また、パラメータを指定していない場合、届かないことがある事に注意する必要があります。これは、優先度の高いReceiverから順次配送されるため、優先度の高いマルウェアが後続のReceiverに配信しないことができるからです
Intent-filter定義がある非公開Broadcast Receiverについて
アプリAが暗黙的IntentをBroadcastした場合、同一アプリ内の非公開のReceiverと同じIntent-filterを定義した、別アプリのReceiverも受信できてしまうため、禁止である。また、BroadcastがOrderedの場合、意図しない結果を受け取ります
ただし、システムの送信するBroadcast Intentのみを受信する場合はexported="false"かつ、Intent-filter定義あり、以外を使用してはいけません。
これは、システムの送信するBroadcast Intentのみexported="false"でも受信可能であり、システムの送信するもの以外を防ぐためです
Broadcast送信した情報がLogCatに出力される場合がある
Broadcastの送受信は基本的にはLogCatに出力されませんが、受信側か送信側のPermission不足によるエラーの際には、送信するIntent情報もエラーログに吐かれてしまうため、注意が必要です
その他
- 非公開Broadcast Receiverでも、同一UIDを持つアプリから、送信されたBroadcastを受信してしまいます。ただし、同一UIDになる場合は、APKを署名する開発者鍵が一致することが保障されているので、セキュリティ上問題ありません
- ホーム画面にショートカットを作る場合、受け手のパッケージ名がわからない場合、暗黙的Intent による公開Receiver への送信となるため、注意が必要です。また、URL を基にしたショートカットを作成する場合、URL に秘密の情報が含まれていることもあるため、注意が必要です
参考
『Android アプリのセキュア設計・セキュアコーディングガイド』【2016年9月1日版】
https://www.jssec.org/dl/android_securecoding.pdf
Android 5.0 Lolipopでレガシー化するもの
http://qiita.com/glayash/items/95174c0fff95cb14c97d