アプリのセキュリティ

アプリの要素

Android はモバイル デバイス向けのオープンソース プラットフォームとアプリ環境を提供します。コア オペレーティング システムは Linux カーネルをベースにしています。多くの場合、Android アプリは Java プログラミング言語で記述され、Android ランタイム(ART)仮想マシンで実行されます。ただし、アプリはネイティブ コードで記述することもできます。アプリは、APK ファイル拡張子を持つ 1 つのファイルからインストールされます。

主な Android アプリ ビルディング ブロックには次のようなものがあります。

  • AndroidManifest.xml: AndroidManifest.xml ファイルは、システムがアプリのすべてのトップレベル コンポーネント(具体的には後述のアクティビティ、サービス、ブロードキャスト レシーバ、コンテンツ プロバイダ)をどう処理すべきかを指示します。また、必要な権限の指定も行います。

  • アクティビティ: アクティビティは、通常は 1 つの、Activity クラスを使用したユーザー向けのタスクのコードです。ほとんどの場合、ユーザーには UI が表示されますが、必ずしも UI を表示する必要はなく、まったく UI を表示しないアクティビティもあります。一般に、アプリのアクティビティの 1 つが、アプリのエントリー ポイントになります。

  • サービス: サービスは、バックグラウンドで実行されるコードの本体です。独自のプロセスで実行することも、別のアプリのプロセスのコンテキストで実行することもできます。他のコンポーネントはサービスに「バインド」し、リモート プロシージャ コールを介してメソッドを呼び出します。サービスの例としては、メディア プレーヤーがあります。ユーザーがメディア選択 UI を終了しても、音楽の再生は続けたいはずです。サービスは、UI が完了しても音楽の再生を継続します。

  • ブロードキャスト レシーバ: BroadcastReceiver は、インテントと呼ばれる IPC メカニズムがオペレーティング システムまたは別のアプリによって発行されたときにインスタンス化されるオブジェクトです。アプリは、たとえばバッテリー残量の低下に関するメッセージのレシーバーを登録し、その情報に基づいて動作を変更できます。

Android 権限モデル: 保護された API へのアクセス

Android 上のすべてのアプリは、アプリ サンドボックスで実行されます。デフォルトでは、Android アプリは限られた範囲のシステム リソースにのみアクセスできます。システムでは、誤って、または不正に使用された場合にデバイスのユーザー エクスペリエンス、ネットワーク、データに悪影響を及ぼすリソースへの Android アプリのアクセスを管理します。

これらの制限はさまざまな形式で実装されています。一部の機能は、機密性の高い機能に対する API を意図的に排除することにより制限されています(たとえば、SIM カードを直接操作するための Android API はありません)。一部の場合では、アプリごとにストレージを分離する場合と同様に、役割を分離することがセキュリティ対策となります。機密情報に関する API は信頼できるアプリによる使用を目的とし、「権限」というセキュリティ メカニズムで保護される場合もあります。

保護対象の API には次のものがあります。

  • カメラ機能
  • 位置情報(GPS)
  • Bluetooth 機能
  • 電話機能
  • SMS/MMS 機能
  • ネットワーク接続とデータ接続

これらのリソースは、オペレーティング システムからのみアクセスできます。保護対象の API をデバイスで使用するには、アプリで必要な機能をマニフェストに定義する必要があります。Android バージョン 6.0 以降ではすべて、実行時の権限モデルを使用します。ユーザーが保護対象の API を必要とするアプリの機能をリクエストすると、システムによりダイアログが表示され、ユーザーはその権限を拒否または許可することを求められます。

付与された権限は、インストールされている限りそのアプリに適用されます。ユーザーの混乱を避けるために、アプリに付与された権限についてシステムがユーザーに再度通知することはなく、コア オペレーティング システムに含まれるアプリや OEM がバンドルしたアプリは、ユーザーに権限を要求しません。アプリがアンインストールされると権限が削除されるため、その後で再インストールすると権限のダイアログが再度表示されます。

ユーザーはデバイスの設定で、以前にインストールしたアプリの権限を表示できます。GPS、無線通信、Wi-Fi を無効にするなど、一部の機能を全体的ににオフにすることもできます。

アプリが、アプリのマニフェストで宣言されていない保護された機能を使用しようとした場合、通常は権限エラーとなり、アプリにセキュリティ例外がスローされます。保護された API の権限チェックは、技術的保護手段の回避を防ぐために可能な限り低いレベルで適用されます。アプリのインストール時に保護対象の API へのアクセスを要求しているメッセージの例を、図 2 に示します

システムのデフォルトの権限については、https://developer.android.com/reference/android/Manifest.permission.html をご覧ください。アプリは他のアプリが使用できるように独自の権限を宣言することができます。そのような権限は上記の場所には記載されていません。

権限を定義する際、protectionLevel 属性は、権限を必要とするアプリについてユーザーに通知する方法や、権限の保持を許可されているユーザーについて、システムに指示します。アプリ固有の権限の作成と使用の詳細については、https://developer.android.com/guide/topics/security/security.html をご覧ください。

SMS ブロードキャスト インテントなど、サードパーティ アプリでは使用できないものの、OEM によって事前にインストールされたアプリで使用できるデバイスの機能がいくつかあります。これらの権限は、signatureOrSystem 権限を使用します。

ユーザーによるサードパーティ製アプリの把握

Android では、ユーザーがサードパーティ アプリを操作しているときにその事実を明確に伝え、そうしたアプリが備えている機能についてユーザーに知らせるよう努めています。アプリのインストール前に、アプリが要求している各種の権限についての明確なメッセージが表示されます。インストール後、ユーザーは再度権限を確認するよう求められません。

インストールの直前に権限を表示する理由はさまざまです。ユーザーが、アプリ、デベロッパー、機能に関する情報を積極的に確認し、自分のニーズや期待に沿っているかどうかを判断するのはインストールの直前です。また、アプリに対する精神的、金銭的なコミットメントをまだ確立しておらず、他のアプリと簡単に比較できることも重要です。

他のプラットフォームの中には、セッションの開始時やアプリの使用中にユーザーに通知して権限を要求するものもあります。Android では、ユーザーがアプリをシームレスに、自由に切り替えられることを重視しています。毎回確認を求めると、ユーザーの操作に時間がかかり、Android のユーザー エクスペリエンスが低下します。インストール時に権限を確認することで、ユーザーは不快に感じた場合にアプリをインストールしないこともできます。

また、多くのユーザー インターフェース研究によると、ユーザーは過剰にプロンプトを表示されると、表示されたすべてのダイアログに対して「OK」と回答するようになることがわかっています。Android のセキュリティ目標の 1 つは重要なセキュリティ情報をユーザーに効果的に伝えることですが、ユーザーがダイアログを無視することに慣れてしまうと、これは実現できません。重要な情報を必要なときに 1 回だけ提示することで、ユーザーが同意を求められている内容についてしっかり確認する可能性が高くなります。

プラットフォームによっては、アプリの機能に関する情報がまったく表示されないこともあります。このような方法では、ユーザーがアプリの機能を簡単に把握したり、それについて議論したりすることができません。すべてのユーザーが常に十分な情報に基づいた判断を下すことはできませんが、Android 権限モデルでは、さまざまなユーザーがアプリに関する情報に簡単にアクセスできます。たとえば、予期しない権限リクエストが表示された場合に、より見識のあるユーザーがアプリの機能に関する重要な質問をし、すべてのユーザーに公開された Google Play のような場所で懸念事項を共有することもできます。

アプリのインストール時の権限 - Google 翻訳 インストール済みアプリの権限 - Gmail
アプリのインストール時の権限 - Google 翻訳 インストール済みアプリの権限 - Gmail

図 1. アプリの権限の表示

プロセス間通信(IPC)

プロセスは、従来の UNIX タイプのメカニズムを使用して通信できます。たとえば、ファイルシステム、ローカル ソケット、シグナルなどがあります。ただし、Linux の権限は引き続き適用されます。

Android では、以下の新しい IPC メカニズムも提供されています。

  • バインダー: インプロセス呼び出しとクロスプロセス呼び出しを実行する際の高パフォーマンスを目的とした、機能ベースの軽量なリモート プロシージャ コール メカニズムです。バインダーは、カスタム Linux ドライバを使用して実装されます。https://developer.android.com/reference/android/os/Binder.html をご覧ください。

  • サービス: サービス(前述)は、バインダーを使用して直接アクセスできるインターフェースを提供できます。

  • インテント: インテントは、何かを行う「意図」を表明するシンプルなメッセージ オブジェクトです。たとえば、アプリがウェブページを表示したい場合、Intent インスタンスを作成してシステムに渡すことで、URL を表示する「意図」を表明します。システムは、このインテントを処理する方法を知っている他のコード(この場合はブラウザ)を見つけて実行します。インテントは、重要なイベント(通知など)をシステム全体にブロードキャストするためにも使用できます。https://developer.android.com/reference/android/content/Intent.html をご覧ください。

  • ContentProvider: ContentProvider は、デバイス上のデータへのアクセスを提供するデータの倉庫です。典型的な例は、ユーザーの連絡先のリストにアクセスするために使用される ContentProvider です。アプリは、他のアプリが ContentProvider を介して公開したデータにアクセスすることも、独自の ContentProvider を定義して独自のデータを公開することもできます。https://developer.android.com/reference/android/content/ContentProvider.html をご覧ください。

ネットワーク ソケットやグローバルに書き込み可能なファイルなど、他のメカニズムを使用して IPC を実装することもできますが、上記の Android IPC フレームワークを使用することをおすすめします。Android デベロッパーは、ユーザーデータの保護とセキュリティの脆弱性の回避に関して、おすすめの方法を使用することが推奨されます。

コストに敏感な API

コストに敏感な API は、ユーザーまたはネットワークに費用が発生する可能性がある機能です。Android プラットフォームでは、OS によって制御される保護対象の API のリストに、コストに敏感な API を配置しています。ユーザーは、コストに敏感な API の使用を要求するサードパーティ アプリに対し、明示的に許可を与える必要があります。この API には、以下が含まれます。

  • 電話
  • SMS/MMS
  • ネットワークとデータ
  • アプリ内課金
  • NFC アクセス

Android 4.2 では、SMS の使用をさらに詳細に管理しています。追加料金が発生する可能性のあるプレミアム サービスを使用するショートコードにアプリが SMS を送信しようとすると、Android によって通知が表示されます。ユーザーは、アプリによるメッセージの送信を許可するかブロックするかを選択できます。

SIM カードへのアクセス

SIM カードへの低レベルアクセスは、サードパーティ アプリでは利用できません。OS は、SIM カードのメモリ上の個人情報(連絡先)へのアクセスを含め、SIM カードとのすべての通信を処理します。また、AT コマンドは無線通信インターフェース レイヤ(RIL)のみで管理されるため、アプリはアクセスできません。RIL は、これらのコマンドに高レベルの API を提供しません。

個人情報

Android では、ユーザーデータへのアクセスを提供する API を、一連の保護対象の API に配置しています。通常の使用時、Android デバイスはユーザーがインストールしたサードパーティ アプリ内のユーザーデータを蓄積します。この情報を共有するアプリでは、Android OS の権限チェックを使用してサードパーティ アプリからデータを保護できます。

機密性の高いユーザーデータへのアクセスは、保護された API を介してのみ可能

図 2. 機密性の高いユーザーデータへのアクセスは、保護された API を介してのみ可能

連絡先やカレンダーなど、個人情報や個人を特定できる情報が含まれる可能性のあるシステム コンテンツ プロバイダは、明確に特定された権限で作成されています。この粒度によって、ユーザーはアプリに提供される可能性のある情報の種類について明確に知ることができます。サードパーティ製アプリは、インストール中にこれらのリソースへのアクセス権を要求する場合があります。権限が付与されると、アプリはインストールされ、インストール時に要求したデータにいつでもアクセスできます。

個人情報を収集するアプリでは、デフォルトで特定のアプリにのみデータの利用が制限されます。アプリで IPC を通じて他のアプリがデータを利用できるようにする場合、アクセスを許可するアプリには、オペレーティング システムが適用する IPC メカニズムに対する権限を適用することができます。

機密データ入力デバイス

Android デバイスでは、カメラ、マイク、GPS など、アプリが周囲の環境とやり取りできる入力デバイスに対して、機密データが頻繁に提供されます。サードパーティ アプリがこれらのデバイスにアクセスするには、ユーザーが Android OS の権限を使用して最初に明示的にアクセス権限を付与する必要があります。インストール時に、センサーへの権限を要求するプロンプトが表示されます。

アプリがユーザーの位置情報を知りたい場合、アプリはユーザーの位置情報にアクセスする権限を必要とします。インストール時に、アプリがユーザーの位置情報にアクセスしてよいかを確認するメッセージが表示されます。アプリが位置情報にアクセスしないようにするには、ユーザーはいつでも「設定」アプリを実行して [位置情報とセキュリティ] に移動し、[無線ネットワークを使用する] と [GPS 機能を ON にする] のチェックボックスをオフにできます。これにより、ユーザーのデバイス上のすべてのアプリについて、位置情報を利用したサービスが無効になります。

デバイスのメタデータ

Android では、本質的に機密でないデータへのアクセスについても制限するよう努めていますが、ユーザーの特徴や好み、デバイスの使用方法が間接的に明らかになる可能性があります。

デフォルトでは、アプリはオペレーティング システムのログ、ブラウザ履歴、電話番号、ハードウェアやネットワークの識別情報にアクセスできません。アプリがインストール時にこの情報へのアクセスを要求した場合は、このアプリが情報にアクセスしてよいかどうかを確認するプロンプトが表示されます。ユーザーがアクセスを許可しない場合、アプリはインストールされません。

認証局

Android には、システム全体で信頼できる、インストール済みのシステム認証局のセットが含まれています。Android 7.0 より前のデバイスでは、デバイス メーカーが出荷時に CA のセットを変更できました。7.0 以降のデバイスではデバイス メーカーによる変更が許可されなくなるため、システム CA のセットは統一されます。

新しいパブリック CA として Android ストックセットに追加するには、CA が Mozilla CA の登録プロセスを完了後、Android(https://code.google.com/p/android/issues/entry)に機能リクエストを申請して、CA を Android オープンソース プロジェクト(AOSP)内のストック Android の CA セットに追加してもらう必要があります。

SMS や MMS のゲートウェイなど、携帯通信会社のインフラストラクチャのコンポーネントに安全にアクセスするために必要なキャリアのプライベート CA のように、AOSP CA のコアセットに含めることのできないデバイス固有の CA もあります。デバイス メーカーには、そうした CA を信頼する必要があるコンポーネントやアプリにのみ、プライベート CA を含めることをおすすめします。詳細については、ネットワーク セキュリティ構成をご覧ください。

アプリの署名

コード署名により、デベロッパーは複雑なインターフェースや権限を作成しなくてもアプリの作成者を特定し、アプリを更新できます。Android プラットフォームで実行されるすべてのアプリには、デベロッパーによる署名が必要です。署名なしでアプリのインストールを試みた場合は、Google Play または Android デバイスのパッケージ インストーラによってインストールが拒否されます。

Google Play におけるアプリ署名は、Google が保証するデベロッパーの信頼性と、デベロッパーが保証するアプリの信頼性をつなぐ役割を果たします。開発されたアプリが、修正などが施されないまま Android デバイスにインストールされることをデベロッパーに対して証明します。アプリの動作についてデベロッパーの責任を明確にする役目もあります。

Android では、アプリをアプリ サンドボックスに配置するときにまず行われるのがアプリへの署名です。署名済みのアプリ証明書は、どのユーザー ID がどのアプリに関連付けられているかを定義するもので、ユーザー ID に応じて異なるアプリが実行されます。アプリ署名を使用することで、明確に定義された IPC を除いて、1 つのアプリが他のどのアプリにもアクセスできないようにします。

アプリ(APK ファイル)を Android デバイスにインストールすると、パッケージ マネージャーによって APK がその APK に含まれる証明書で適切に署名されているかどうかの検証が行われます。証明書(正確には証明書の公開鍵)がデバイス上の他の APK の署名に使用されるキーと一致する場合、新しい APK には、同様に署名された他の APK と UID を共有することをマニフェストで指定するというオプションがあります。

アプリは、サードパーティ(OEM、オペレータ、代替マーケター)が署名するか、自己署名されます。Android は、外部の支援や許可を必要とすることなくデベロッパーが生成できる、自己署名証明書を使用したコード署名を提供します。アプリについては、認証局の署名は必要はありません。Android では現在、アプリ証明書の CA 認証確認を行っていません。

アプリは、署名保護レベルでセキュリティ権限を宣言することもできます。これにより、同一の鍵で署名されたアプリのみにアクセスを制限し、異なる UID とアプリ サンドボックスを維持できます。同じデベロッパーの鍵で署名された 2 つ以上のアプリについては、共有 UID をマニフェストで宣言できる共有 UID 機能を通じて、共有アプリ サンドボックスとの密接な関係性が保たれます。

アプリの確認

Android 4.2 以降ではアプリの確認がサポートされています。ユーザーは「アプリの確認」を有効にして、インストール前にアプリの検証ツールでアプリを評価できます。害を及ぼす可能性があるアプリをユーザーがインストールしようとすると、アプリの確認がユーザーに警告することがあります。特に有害なアプリの場合、インストールをブロックすることもあります。

デジタル著作権管理

Android プラットフォームは、コンテンツに関連付けられたライセンス制約に従って、アプリが著作権で保護されたコンテンツを管理できる、拡張可能なデジタル著作権管理(DRM)フレームワークを提供します。DRM フレームワークは多くの DRM スキームをサポートしています。デバイスがサポートする DRM スキームはデバイス メーカーによります。

Android DRM フレームワークは、次の 2 つのアーキテクチャ レイヤに実装されています(下記の図を参照)。

  • DRM フレームワーク API。Android アプリ フレームワークを介してアプリに公開され、標準アプリ用の ART VM を介して実行されます。

  • ネイティブ コード DRM マネージャー。DRM フレームワークを実装して DRM プラグイン(エージェント)のインターフェースを公開し、さまざまな DRM スキームの権利の管理と復号を行います。

Android プラットフォームでのデジタル著作権管理のアーキテクチャ

図 3. Android プラットフォーム上の DRM のアーキテクチャ