第1回は「ToDoリストアプリ」を題材に、

  1. 外部とのアクセスの確認
  2. データの適切な保存とその保護の確認
  3. WebViewの利用方法の確認
  4. Lintのセキュリティ警告の確認
  5. 利用しているライブラリの脆弱性を確認
  6. ログ出力の確認

のチェックリストのうち、3番までを解説しました。今回は、4番以降を解説します。

4. Lintのセキュリティ警告の確認

エンジニアが手作業でチェックすることも大事ですが、チェック前に”自動化”することも重要です。ツールを活用すれば、チェックする時間コストを大きく下げられます。

Androidにはlintというツールがあります。lintはアプリのソースコードを静的解析して、潜在的な課題を抽出してくれます。パフォーマンスなど、抽出したい課題がカテゴリ別に分かれていますが、その中に「セキュリティ」も用意されています(下記の図は開発者サイトからの引用です)。

lintを用いた解析

lintはAndroid Studioから起動できます。

Android Studio上からInspect Code…を選択し、lintを起動 (Analyze -> Inspect Code…)

Android Studio上でのlintの警告を確認

また、lintで確認できるセキュリティの項目はlint --show Securityコマンドで出力することができます。

$ lint --show Security

AddJavascriptInterface
----------------------
Summary: addJavascriptInterface Called

Priority: 9 / 10
Severity: Warning
Category: Security
~略~

lintのチェック項目一覧は、(lint-checks)でも参照できます。ぜひ活用してください。

重要な情報をハードコードしていませんか?

パスワードなどの重要なデータをハードコードしていないか確認します。Androidは、リバースエンジニアリングできるツールが揃っており、アプリがどういう造りになっているか、容易に知ることができます。

例えば、アプリ内部で重要なアルゴリズムを実装していないか確認してください。もし実装している場合は、高度な難読化ツールを導入するか、可能であればサーバーサイドにアルゴリズム処理を移して実行するように変更しましょう。

5. 利用しているライブラリの脆弱性を確認

忘れてはならないのが、アプリで利用しているライブラリです。仮に、開発しているアプリのセキュリティ対策が万全だったとしても、利用しているライブラリに脆弱性があれば、攻撃者はそこを狙います。

「build.gradleのdependencies」を参照し、利用しているライブラリを確認しましょう。

dependencies {
    compile "com.android.support:support-v4:23.1.0"
    compile fileTree(dir: 'libs', include: ['*.jar'])
    testCompile 'junit:junit:4.12'
    ...
    ...
}

また、Gradleの依存解決によって「意図していなかったライブラリが含まれる」といったリスクがあるため、依存関係ツリーの確認も有効な手段です。androidDependenciesを実行して、依存関係ツリーを確認しましょう。

./gradlew androidDependencies

:app:androidDependencies
....

prodRelease
+--- com.google.android.gms:play-services-ads:10.0.1
|    +--- com.google.android.gms:play-services-ads-lite:10.0.1
|    |    \--- com.google.android.gms:play-services-basement:10.0.1
|    |         \--- com.android.support:support-v4:25.1.0
...

自分たちが利用しているバージョンより新しいバージョンで脆弱性への対応が行われていれば、新しいバージョンに更新してください。OSSを利用している場合は、OSSのGithub通知や、関連コミュニティのメーリングリストなどに登録し、定期的に情報を確認しておきましょう。

ここのポイントは以下の2点です。

  1. build.gradleを参照し、利用しているライブラリを確認する
  2. 利用しているライブラリに脆弱性対応があった場合は、修正されたバージョンに更新を行う

6. ログ出力

IDやパスワードなどの認証情報、氏名や住所などの個人情報を、開発や調査のためにログに出力していませんか? もちろん、それらの目的には問題ありませんが、リリースする際はデバッグログなどの不要なログ出力をやめましょう。ログ出力はパフォーマンスに影響するほか、監視によってデータを盗聴される恐れがあります。

リリース時に「Logcat」でログ出力をしないようにする方法は2つあります。

Proguardでログ出力をしているコードを削除する

proguard.proファイルに、以下のようなコードを追加します(Logクラスをラップしてログ出力をしている場合は、ラップしたクラスを指定)。

-assumenosideeffects class android.util.Log {
    public static *** d(...);
    public static *** v(...);
    public static *** i(...);
    public static *** w(...);
    public static *** e(...);
}

ログ出力用のフラグを持ち、コンパイル時に削除する

if文が少し気になりますが、個人的にはコード上で表現できてわかりやすいため、こちらの方が好みです。

if (BuildConfig.DEBUG) Log.d("TAG", "XXX Logging");

なおAndroid 4.1(Jelly Bean)より、サードパーティのアプリからREAD_LOGSパーミッションを取得できなくなりました。

LogCatのログ出力をサードパーティアプリに読み取られる可能性は低くなったものの、それでも開発やデバッグ用のログ出力を行わない方が良いでしょう。デバッグのログ出力によって、攻撃者がアプリを解析する手助けになり、思わぬところから標的になってしまう可能性があるからです。

まとめ

今回は「ToDoアプリのセキュリティチェック」という想定で6つのチェックを行いましたが、みなさんの開発しているアプリではどうでしょうか? すべて問題ないということであれば「素晴らしい」の一言です。もし、アプリ開発においてセキュリティのチェックリスト、ガイドラインを設けていなければ、この連載を参考に作成してみてはいかがでしょうか?

アプリの種類によっては、リバースエンジニアリング対策やなりすまし対策といったさらなる対策が必要になりますが、まずは「基本のセキュリティチェック」が重要です。チェックと対策を定期的に実施することが最善の道といえます。また、チーム開発の場合は、チーム内でセキュリティ勉強会を開き、情報共有だけでなく、セキュリティ意識を高めることも大切だと思います。

開発を続けていくことで、当然ながら新しいコードの追加やライブラリの導入というケースが想定されます。一方で、開発を中断しているアプリでも、Androidプラットフォームに脆弱性が見つかったり、セキュリティ機能の進化といった外的要因による対応が求められるケースもあることを忘れてはなりません。

これらに対処するにはなかなか骨を折る仕事だと思いますが、常日頃からセキュリティに目を光らせ、セキュアなアプリをリリースすることが、最終的に「アプリユーザーの安心・安全」に繋がることを心にとどめ、大事にしていきたいですね。

著者紹介


筒井 俊祐(つつい しゅんすけ)
ヤフー パーソナルサービスカンパニー アプリ開発部 部長

2005年ヤフー株式会社入社。2009年よりAndroidアプリ開発に従事し「ヤフオク!」、「Yahoo!ブラウザー」、「Yahoo!かんたんバックアップ」など多数のアプリ開発業務を行ってきた。

2013年Androidの黒帯に認定され、社内エンジニアの技術力強化にも携わっている。著作に「黒帯エンジニアが教えるプロの技術 Android開発の教科書」がある。