セキュリティの実装

Android セキュリティ チームには、Android デバイスにおけるセキュリティ上の潜在的な問題の防止に関する情報のリクエストが定期的に寄せられます。また、不定期にデバイスのスポット チェックを行い、デバイスのメーカーや影響を受けるパートナーに、潜在的な問題について知らせています。

このページには、Google の経験に基づくセキュリティに関するおすすめの方法が記載されています。これは開発者向けの設計セキュリティ ガイドの内容を拡張したものです。また、このページではデバイス上でシステムレベルのソフトウェアを構築またはインストールする場合に特有の詳細情報も記載されています。

上記おすすめの方法の採用を促進するため、Android セキュリティ チームは Android 互換性テストスイート(CTS)と Android Lint にテストを統合しています。デバイスの実装者は、他の Android ユーザーにとって有用なテストを提供することが推奨されます(root/cts/tests/tests/security/src/android/security/cts のセキュリティ関連テストをご覧ください)。

開発プロセス

開発プロセスと開発環境では、次のおすすめの方法を使用します。

ソースコードのレビュー

ソースコードのレビューでは、このドキュメントに掲載されているような広範なセキュリティ問題を検出できます。手動と自動の両方でのソースコードのレビューを強くおすすめします。ポイント:

  • Android SDK を使用してすべてのアプリケーション コードに Android Lint を実行し、特定された問題を修正します。
  • バッファ オーバーフローや off-by-one エラーなど、メモリ管理の問題を検出できる自動ツールを使用してネイティブ コードを分析する必要があります。
  • Android ビルドシステムは、AddressSanitizer や UndefinedBehaviorSanitizer など、この目的で使用できる多くの LLVM サニタイザをサポートしています。

自動テストの使用

自動テストでは、以下で紹介している問題などの広範なセキュリティ問題を検出できます。ポイント:

  • CTS のセキュリティ テストは随時更新されています。CTS の最新バージョンを実行して互換性を確認してください。
  • 開発プロセス全体を通じて CTS を定期的に実行することで、問題を早期発見し、修正までの時間を短縮します。Android では 1 日に何度も行われる自動ビルドプロセスで CTS を継続的インテグレーションの一環として使用しています。
  • デバイス メーカーはインターフェースのセキュリティ テストを自動化してください。不正入力のテスト(ファズテスト)などがこれに該当します。

システム イメージの署名

システム イメージの署名は、デバイスの整合性を決定する際に重要です。ポイント:

  • デバイスには、公開されている鍵で署名してはいけません。
  • デバイスの署名に使用される鍵は、制限付きで監査可能なアクセスを提供するハードウェア セキュリティ モジュール(HSM)など、業界基準に従った機密鍵の取り扱い方法により管理します。

アプリへの署名(APK)

アプリ署名はデバイスのセキュリティで重要な役割を果たし、権限の確認やソフトウェアの更新に使用されます。アプリ署名に使用する鍵を選択する際は、アプリが 1 つのデバイスでのみ利用されるのか、複数のデバイスにまたがって使用されるのかを考慮することが重要です。 ポイント:

  • アプリには、公開されている鍵で署名してはいけません。
  • アプリの署名に使用される鍵は、制限付きで監査可能なアクセスを提供する HSM など、業界基準に従った機密鍵の取り扱い方法により管理します。
  • アプリはプラットフォーム鍵で署名しないでください。
  • パッケージ名が同じであるアプリは別々の鍵で署名しないでください。これは、プラットフォーム鍵を使用する場合など、さまざまなデバイス用にアプリを作成する場合によく発生します。アプリがデバイスに依存しない場合は、デバイス間で同じ鍵を使用します。アプリがデバイス固有の場合は、デバイスと鍵ごとに固有のパッケージ名を作成します。

アプリの公開

Google Play では、デバイスのメーカーは完全なシステム アップデートを行わずにアプリを更新できます。これにより、セキュリティ問題への迅速な対応や新しい機能の提供ができるようになり、またアプリのパッケージが一意になるようにすることもできます。ポイント:

  • アプリを Google Play にアップロードすると、完全な無線(OTA)アップデートを行わずに自動更新できます。アップロードされていてまだ公開されていないアプリは、ユーザーが直接ダウンロードすることはできませんが、アプリの更新は行われます。以前にこのアプリをインストールしたユーザーは、このアプリの再インストールや、他のデバイスへのインストールが可能です。
  • 会社の商標を使用するなどの方法により、会社に明示的に関連付けられたアプリ パッケージ名を作成します。
  • 第三者のユーザーによるパッケージ名のなりすましを防ぐため、デバイスのメーカーが公開するアプリは Google Play ストアにアップロードする必要があります。 デバイスのメーカーが、Play ストアで公開されていないアプリをデバイスにインストールした場合、別のデベロッパーが同じアプリをアップロードし、同じパッケージ名を使用して、アプリのメタデータを変更することが可能となります。ユーザーがこのアプリを使用する場合、関連性のないメタデータが原因で混乱が生じることがあります。

インシデントへの対応

デバイス固有のセキュリティ問題が発生した場合に、外部の当事者がデバイスのメーカーに問い合わせできる必要があります。セキュリティ インシデントを管理するために、一般公開用のメールアドレスを作成することをおすすめします。ポイント:

  • security@your-company.com のようなアドレスを作成して公開します。
  • Android OS や複数のデバイス メーカー製の Android デバイスに影響するセキュリティ上の問題に気付いた場合は、セキュリティ バグレポートを使用して Android セキュリティ チームにお問い合わせください。

サービスの導入

サービスの導入時には、次のおすすめの方法に従ってください。

ルートプロセスの分離

ルートプロセスは、権限昇格攻撃で最も狙われるターゲットです。そのため、ルートプロセスの数を減らすと、権限昇格のリスクが減少します。CTS には、ルートプロセスを一覧表示する情報テストが含まれています。ポイント:

  • デバイスはルートとして最低限必要なコードを実行するようにしてください。できるだけルートプロセスではなく通常の Android プロセスを使用します。ICS Galaxy Nexus のルートプロセスは vold、inetd、zygote、tf_daemon、ueventd、init の 6 つだけです。プロセスをデバイスでルートとして実行する必要がある場合は、公開でレビューができるようにプロセスを AOSP 機能リクエストで文書化します。
  • 可能であれば、ルートコードは信頼できないデータから分離し、IPC を介してアクセスするようにします。たとえば、ルート機能を Binder 経由でアクセスできる小規模なサービスに縮小し、ネットワーク トラフィックを処理する権限が小さいかまったくない署名権限をアプリに与えてこのサービスを公開します。
  • ルートプロセスはネットワーク ソケットでリッスンしないでください。
  • ルートプロセスには、Java VM などのアプリ用汎用ランタイムを含めないでください。

システムアプリの分離

一般に、プリインストールされたアプリは共有システムの UID で実行しないでください。ただし、アプリがシステムや他の特権サービス(電話など)の共有 UID を使用する必要がある場合は、ユーザーがインストールしたサードパーティ製アプリからアクセスできるサービス、ブロードキャスト レシーバ、コンテンツ プロバイダはエクスポートしないでください。ポイント:

  • デバイスはシステムとして最低限必要なコードを実行する必要があります。可能であれば、システム UID を再使用するのではなく、独自の UID を保有する Android プロセスを使用します。
  • 可能であれば、システムコードは信頼できないデータから分離し、IPC は他の信頼できるプロセスにのみ公開します。
  • システム プロセスは、ネットワーク ソケットでリッスンしないでください。

プロセスの分離

Android アプリ サンドボックスは、アプリがルートプロセスやデバッガなど、システム上の他のプロセスと分離していることを想定しています。デバッグがアプリとユーザーによって特別に有効にされていない限り、アプリがこの想定に反しないようにする必要があります。ポイント:

  • ドキュメント化された Android のデバッグ方法を使用しない場合は、ルートプロセスが個々のアプリのデータフォルダ内にあるデータにアクセスしないようにしてください。
  • ドキュメント化された Android のデバッグ方法を使用しない場合は、ルートプロセスがアプリのメモリにアクセスしないようにしてください。
  • 他のアプリやプロセスのデータやメモリにアクセスするアプリがデバイスに含まれないようにしてください。

SUID ファイルの保護

信頼できないプログラムが新しい setuid プログラムにアクセスできないようにしてください。setuid プログラムにはルートアクセスを可能にする脆弱性が生じることが多いため、信頼できないアプリケーションが setuid プログラムを利用する可能性を最小限に抑えてください。ポイント:

  • SUID プロセスには、Android セキュリティ モデルを回避可能にするためのシェルやバックドアを指定しないでください。
  • SUID プログラムはどのユーザーからも書き込みできないようにする必要があります。
  • SUID プログラムは、誰でも読み取りや実行ができる状態にしてはいけません。グループを作成し、そのグループのメンバーに対して SUID バイナリへのアクセスを制限して、SUID プログラムを実行できるアプリケーションをそのグループに配置します。
  • SUID プログラムは、デバイスのユーザー ルーティングの一般的なソースです。この危険を抑えるため、シェルユーザーが SUID プログラムを実行できないようにする必要があります。

CTS 検証ツールには SUID ファイルの情報テストリストが含まれています。一部の setuid ファイルは CTS テストで許可されません。

リスニング ソケットの保護

デバイスが任意のインターフェース上の任意のポートでリッスンしている場合、CTS テストは失敗します。エラーが発生した場合、Android は次のおすすめの方法が使用されているか確認します。

  • デバイスにリスニング ポートがないようにする必要があります。
  • リスニング ポートは OTA なしで無効にできなければなりません。これは、サーバーまたはユーザー デバイスの構成の変更により行います。
  • ルートプロセスはどのポートでもリッスンしないでください。
  • システム UID が所有するプロセスはどのポートでもリッスンしないでください。
  • ソケットを使用するローカル IPC では、アプリは特定のグループにアクセスを限定した UNIX ドメインのソケットを使用する必要があります。IPC 用のファイル記述子を作成し、特定の UNIX グループに対して +RW にします。すべてのクライアント アプリはその UNIX グループに属している必要があります。
  • 無線やモデムがアプリのプロセッサとは別になっているような、複数のプロセッサを搭載したデバイスでは、プロセッサ間の通信にネットワーク ソケットを利用するものもあります。そのような場合、プロセッサ間の通信に利用されるネットワーク ソケットでは独立したネットワーク インターフェースを使い、デバイス上の許可されていないアプリによるアクセスを防ぐ(つまり、iptables を使用してデバイス上の他のアプリによるアクセスを防ぐ)必要があります。
  • リスニング ポートを処理するデーモンは、不正な形式のデータに対して堅牢である必要があります。 Google は、許可されていないクライアントと、可能であれば許可されたクライアントを使用して、ポートに対してファズテストを実行する場合があります。クラッシュは所定の重大度のバグとして報告されます。

データのログ

データをログに記録すると、そのデータの漏洩リスクが高まり、また、システムのパフォーマンスが低下します。Android デバイスにデフォルトでインストールされているアプリが重要なユーザーデータをログに記録した結果発生したセキュリティ インシデントが複数報告されています。ポイント:

  • アプリやシステム サービスが、機密情報を含んでいる可能性のあるサードパーティ アプリのデータについてログを記録しないようにする必要があります。
  • アプリが通常の動作の一環として個人情報(PII)のログを記録しないようにする必要があります。

CTS にはログ内に機密情報の可能性がある情報が存在するかどうかを確認するテストが含まれます。

ディレクトリへのアクセスの制限

グローバルに書き込み可能なディレクトリでは、セキュリティ上の弱点が生じ、信頼されているファイルの名前の変更、ファイルの置き換え、シンボリック リンク ベースの攻撃(攻撃者はファイルへのシンボリック リンクを使用して信頼されているプログラムをだまし、本来想定されていない処理を実行させる)をアプリができるようにする可能性があります。また、書き込み可能なディレクトリでは、アプリケーションをアンインストールしても、アプリケーションに関連付けられたすべてのファイルを適切にクリーンアップできないことがあります。

システムまたは root ユーザーにより作成されたディレクトリは、グローバルに書き込み可能にしないことをおすすめします。CTS テストでは、既知のディレクトリをテストすることによりこのおすすめの方法が強制適用されます。

構成ファイルの保護

多くのドライバとサービスは、/system/etc/data などのディレクトリに保存されている構成とデータファイルに依存しています。これらのファイルが特権プロセスにより処理され、グローバルに書き込み可能である場合、アプリが悪意のあるコンテンツをこのグローバルに書き込み可能なファイルに作成することによって、このプロセスの脆弱性を悪用することが可能となります。ポイント:

  • 特権プロセスによって使用される構成ファイルは、誰でも読み取れるようにはしないでください。
  • 特権プロセスによって使用される構成ファイルは、グローバルに書き込み可能にしてはいけません。

ネイティブ コード ライブラリの保存

デバイスのメーカーの特権プロセスで使用されるコードを /vendor/system で使用してはいけません。これらのファイルシステムは、起動時に読み取り専用としてマウントされます。システムやその他の高い権限を持つデバイス上のアプリで使用されるライブラリもこれらのファイルシステムに配置することが強く推奨されます。これにより、特権プロセスが実行するコードを攻撃者が制御できるようになるセキュリティの脆弱性を回避できます。

デバイス ドライバへのアクセスを制限する

ドライバに直接アクセスできるのは信頼されたコードのみにする必要があります。可能であれば、推奨されるアーキテクチャは、プロキシが呼び出す単一目的のデーモンをドライバに対して指定し、ドライバにはそのデーモンしかアクセスできないよう制限することです。おすすめの方法として、ドライバ デバイス ノードは誰でも読み取りや書き込みができる状態にはしないでください。CTS テストでは、公開されているドライバの既知のインスタンスをチェックすることにより、このおすすめの方法が強制適用されます。

ADB の無効化

Android Debug Bridge(ADB)は重要な開発およびデバッグ用ツールですが、管理された安全な環境で使用することが想定されていますので、通常の使用時には有効にしないでください。ポイント:

  • ADB はデフォルトで無効にする必要があります。
  • 接続を承認する前に、ユーザーが ADB をオンにする必要があります。

ブートローダーのロック解除

多くの Android デバイスはロック解除をサポートしており、これによりデバイスの所有者がシステム パーティションの変更や、カスタム オペレーティング システムのインストールを行うことができます。一般的な例として、サードパーティの ROM をインストールし、デバイスでシステムレベルの開発を行うことが挙げられます。たとえば、Google Nexus デバイスのオーナーは fastboot oem unlock を実行してロック解除プロセスを開始できます。このとき次のメッセージがユーザーに表示されます。

Unlock bootloader?

ブートローダーのロックを解除すると、このスマートフォンにカスタム オペレーティング システム ソフトウェアをインストールできます。

カスタム OS は、元の OS と同じテストの対象ではなく、お使いのスマートフォンやインストール済みのアプリが正常に動作しなくなる可能性があります。

個人データへの不正なアクセスを防ぐため、ブートローダーのロックを解除すると、スマートフォンからの個人データもすべて削除(データの初期化)されます。

音量大 / 小ボタンを押して [Yes] または [No] を選択し、電源ボタンを押して続行します。

Yes: ブートローダーのロックを解除します(保証が無効になる場合があります)。

No: ブートローダーのロックを解除およびスマートフォンの再起動を行いません。


ロック解除可能な Android デバイスはロック解除前にすべてのユーザーデータを安全に消去することをおすすめします。ロック解除時にすべてのデータを適切に削除しないと、物理的に近接した攻撃者が機密情報である Android ユーザーデータへのアクセスを不正に行う可能性があります。ユーザーデータの開示を防止するには、ロック解除をサポートするデバイスに適切にロック解除が実装されている必要があります(デバイスのメーカーによるロック解除の実装が適切でない事例が多くあります)。適切に実装されたロック解除プロセスには、次のプロパティがあります。

  • ユーザーがロック解除コマンドを確認したら、デバイスがすぐにデータのワイプを開始する必要があります。安全に削除が完了するまで、unlocked フラグを設定しないでください。
  • 安全に削除を完了できない場合、デバイスはロックされた状態のままでなければなりません。
  • ioctl(BLKSECDISCARD) または同等のものが下位のブロック デバイスでサポートされている場合は、これを使用する必要があります。eMMC デバイスでは、Secure Erase または Secure Trim コマンドを使用します。eMMC 4.5 以降の場合は、通常の Erase または Trim に続いて Sanitize 操作を使用します。
  • BLKSECDISCARD が下位のブロック デバイスでサポートされていない場合、ioctl(BLKDISCARD) を代わりに使用する必要があります。eMMC デバイスでは、通常の Trim 操作を行います。
  • BLKDISCARD がサポートされていない場合、ブロック デバイスをすべてゼロで上書きすることは認められます。
  • エンドユーザーが、パーティションをフラッシュする前のユーザーデータのワイプを必須にできるようにしなければなりません。たとえば、Nexus デバイスの場合は、fastboot oem lockコマンドを使用します。
  • デバイスは、eFuse または同様のメカニズムを使用して、デバイスのロック解除や再ロックが行われたかどうかを記録できます。

上記の要件により、ロック解除操作が完了すると、すべてのデータが破棄されます。これらの保護を実装していない場合は、中レベルのセキュリティ脆弱性があると見なされます。

ロック解除されたデバイスを再度ロックするには fastboot oem lock コマンドを使用します。ブートローダーをロックすると、元のデバイス メーカーの OS と同じように、新しいカスタム OS によりユーザーデータが保護されます。たとえば、デバイスのロックが再度解除された場合はユーザーデータが消去されます。