JSSECが公開している『Androidアプリのセキュア設計・セキュアコーディングガイド』の2016-09-01版を共有用にまとめているもののうち、「4.6. ファイルを扱う」のものとなります
詳細やサンプルコードについては原著の方を参考ください
チェックポイント
- 出来る限り、非公開ファイルにしている
- アプリ間の情報交換を行う場合、別のAndroidの仕組みを利用して、直接ファイルにアクセスさせない
- ファイルに格納する(された)情報は、内容の安全性を確認する
非公開ファイル
同一アプリ内のみの読み書きを使用するため、安全です。
- ファイルはアプリディレクトリ内に作成している
- ファイルのアクセス権がプライベートモードになっている
読み取り公開ファイル
不特定多数のアプリに対して、内容のみを公開するためのファイルとなります
- ファイルはアプリディレクトリ内に作成している
- ファイルのアクセス権は他のアプリに対しては読み取り専用モードになっている
- MODE_WORLD_READABLEを使用していない(推奨。API LEVEL17以降でdeprecatedのため)
- センシティブな情報を含めていない
読み書き公開ファイル
不特定多数のアプリに対して、読み書きを許可するファイルとなります。誰でも、読み書き可能という事は、
- マルウェアが書き換えが可能であり、信頼性、安全性がない
- ファイル内のデータ形式やタイミングの制御が困難
そのため、他アプリから読み書き可能なアクセス権を設定したファイルは原則作るべきではありません
外部記憶(読み書き公開)ファイル
不特定多数のアプリに対して、読み取り公開ファイル、または、読み書き公開ファイルと同等の性質を持つため、使用は最小限にとどめるべきである
- アプリごとにユニークなディレクトリにファイルを配置する
- 利用側のアプリで書き込みを行わない仕様にする
- 原則、センシティブな情報を保存しない。使用する場合は、暗号化している
- 改竄されて困る情報を保存する場合、電子署名も一緒に保存している
- いつでも、そのファイルを削除されることを想定してアプリを設計している
- バックアップなどを出力する場合は、警告表示をしている(推奨。後述)
Tips
外部記憶(読み書き公開)ファイルについて
SDカード等外部記憶デバイスは十分なアクセス権のコントロールが出来ず、また、他アプリからファイルの読み書き、削除が可能なため、機能上どうしても必要な場合のみ、最小限での利用をすべきです
例えば、容量の大きなファイルや、別の場所への情報の移動目的な場合を使用する場合には使用しますが、センシティブな情報を含めてはいけません。含める場合は、暗号化などの対策が必要となります
また、Androidアプリの慣例として、バックアップファイルは外部記憶デバイス上に作成されることが多いですが、マルウェアを含む他アプリから削除や改ざんのリスクがあります
そのため、バックアップファイルをPC等の安全な場所にコピーしてくださいといった警告表示など、アプリの仕様や設計面でのリスク最小化が必要です
ファイルの生存期間について
アプリディレクトリ内に保存されたデータは
- アプリのアンインストール
- 各アプリのデータおよびキャッシュの消去
で削除されます。そのため、期間はアプリの生存期間より短くなります
外部記憶デバイスのファイルはアプリの生存期間より、ファイルの生存期間が長く、また、以下の状況を想定する必要があります
- ユーザ、または、マルウェアなどによるファイルの消去
- SDカードの抜き取り・差し替え・アンマウント
そのため、アプリとしての動作を実現する意味でも、ファイルの保存場所を正しく選択する必要があります
ファイルディスクリプタ経由のファイル共有
公開ファイルを直接アクセスさせるのではなく、ファイルディスクリプタ経由でファイルを共有する方法があり、Content ProviderとServiceで使用できます。
それらの中で、非公開ファイルをオープンし、そのファイルディスクリプタを相手のアプリに渡すことで、アクセス権の制御やアクセス許可するアプリの範囲が制御できます
ただし、書き込み、追記を許可した場合、ファイルの完全性が保証しづらくなるので、読み込みのみを許可するのが望ましいです
ディレクトリのアクセス権
ファイルのディレクトリにもセキュリティの考慮が必要です。基本的にディレクトリは非公開にすべきです。
Context#getDir( String name, int mode )を使用する場合、modeにMODE_WORLD_READABLE,MODE_WORLD_WRITABLEを使用してはいけません(API Level17から非推奨)
Android 4.4以降の外部ストレージへのアクセスに関する仕様変更について
Android4.4以降では外部ストレージへのアクセスに関してのが以下のように仕様が変更されています
- 外部ストレージ上のアプリ固有ディレクトリに読み書きする場合は、WRITE_EXTERNAL_STORAGE/READ_EXTERNAL_STORAGE Permissionが不要になった
- 外部ストレージ上のアプリ固有ディレクトリ以外を読みこむ場合は、WRITE_EXTERNAL_STORAGE/READ_EXTERNAL_STORAGE Permissionが必要になった
- プライマリ外部ストレージ上のアプリ固有ディレクトリ以外を書き込む場合は、以前と同じように、WRITE_EXTERNAL_STORAGEが必要
- セカンダリ外部ストレージ上のアプリ固有ディレクトリ以外への書き込みが不可能(Android5.0以降では実装とユーザの許可次第では可能)
そのため、Android4.4をまたぐアプリで、1のみに該当する場合はにmaxSdkVersionを指定して対応するのが望ましいです
参考
『Android アプリのセキュア設計・セキュアコーディングガイド』【2016年9月1日版】
https://www.jssec.org/dl/android_securecoding.pdf