JSSECが公開している『Androidアプリのセキュア設計・セキュアコーディングガイド』の2016-09-01版を共有用にまとめているもののうち、「4.8. LogCatにログ出力する」のものとなります
詳細やサンプルコードについては原著の方を参考ください
リリース版でも出力し、ユーザーが参照可能であるものを運用ログと表現します
リリース版アプリでは出力せず、ユーザーが参照不可能な想定のログを開発ログと表現します
チェックポイント
- リリース版では、センシティブな情報をログ出力をしていない
- センシティブな情報は運用ログ(Log.e/w/i,System.out /err)で出力しない
- Throwableオブジェクトのログ出力には、Log.d/vを使用する
-
ログ出力にはandroid.util.Logクラスのみを使用する(推奨)
- System.out/ errでは運用ログと開発ログを分けれないため。また、LogとSystemを両方使用する場合、考慮することが増えることによるミスの発生を防ぐため、Logのみを使用するのが好ましい
Tips
LogCatについて
LogCatとはシステムだけでなく、アプリのログ情報も出力されます
LogCatのログ情報は、4.1未満では同じ端末の他アプリから読み取れたり、ADB経由での参照も可能なため、LogCatにはセンシティブな情報を出力すべきではありません。また、リリース版アプリでは必要のないログは出力しないことが望ましいです
リリース版のログ出力の考え方
ログ出力の考え方として2パターンあります
- セキュリティ観点と出力することの価値の少なさを考えて、一切ログ出力しないという考え方。リリース後のアプリのLogCatの情報を開発者が取得する方法がなく、センシティブな情報が漏れる可能性があるため
- カスタマーサポートなどの不具合解析の最終手段として、解析に必要な情報をログに出力すべきという考え方。ただし、こちらの場合、センシティブな情報を誤ってログ出力しないように注意する必要があります
ログレベルと、ログ出力メソッドの選択
運用ログとして
- アプリが致命的な状況に陥った時に出力するLog.e
- アプリが深刻な予期せぬ状況に陥った時に出力するLog.w
- 上記以外で、アプリの注目すべき状態や情報を出力するLog.i
開発ログとして
- 特定のバグ原因究明のために一時的にログ出力するLog.d
- 運用、開発含め、上記に当てはまらないログを出力するLog.v
ただし、これらは、あくまで使い分の考え方、作法のようなものであり、Log.dもLog.vも、リリースビルドでもログを出力するため、自前で削除したりする必要があります
開発ログの削除
開発ログはリリース時には、出力されてはいけません。そのため、proGuardを用いて、自動で削除してしまうのが好ましいです。ただし、proGuardを使用して削除する場合、以下に関して考慮が必要です
- 戻り値を使用した場合、削除されない
- リリースビルド以外で作成した場合、削除されない
- Logの出力のために作成したString等は逆アセンブルで見ることも可能
- proGuardの設定がされていない他のプロジェクトでコードの再利用すると、漏洩する危険がある
Intentの内容がLogCatに出力される
Activityを利用する際に、ActivityMangerがIntentの内容のうち、利用先パッケージ名、利用先クラス名、intent#setDataで設定したURIをLogCatで出力するため、どのようなactivityであっても、これらにセンシティブな情報が含まれないようにする必要があります
System.out /errに出力されるログの抑制
System.out/ errの出力先はLogCatのため、読み取ることが出来ます。また、下記の場合も出力されます
- Exception#printStackTrace()を利用する場合
- 暗黙的に出力される場合(例外をアプリでキャッチしていない場合)
スタックトレースはアプリ固有情報があるため、例外は開発者が正しくハンドリングすべきです
保険的対策として、System.out/ errの出力先を変更、出力をしない方法がありますが、問題がないかを検討する必要があります。また、システムプロセスのエラーログを抑制はできません
参考
『Android アプリのセキュア設計・セキュアコーディングガイド』【2016年9月1日版】
https://www.jssec.org/dl/android_securecoding.pdf