連載
» 2011年06月06日 00時00分 公開

デバッグ情報にご用心!イチから始める! Androidセキュリティ(3)(2/3 ページ)

[杉山俊春, Illustrated by はるぷ,株式会社ユービーセキュア]

たかがログ出力、されどログ出力

クウ 「うぬー。よく分からん……。なんでこんなことになるんだ?」

ナツ 「また何か変なことしてるのー?」

クウ 「ナツさん、聞いてくださいよ。なんか、またユウヤにやられちゃったんです……」

ナツ 「あらら。……ユウヤはAndroidについて、いろいろ詳しいみたいだね」

クウ 「そうなんですよー。基本、いろんなことに興味なさそうにしてるのに」

ユウヤ 「あ、いや……。別に興味あるわけじゃないですよ。Androidアプリとか作ったこともないですし……」

ナツ 「ふむ……それはそれで不思議だね。……いつも二人の会話聞いててちょっと気になってたことがあるんだけど、ユウヤ、後でちょっといいかなー?」

ユウヤ 「え……。そんなに不思議なことはないですよ」

クウ 「ユウヤは実はAndroidには興味あるのかー」

ナツ 「とりあえず、クウはまたお勉強かな〜」

クウ 「はい〜」

悩むクウ

 今回クウの作成したAndroidアプリケーションでは、標準出力へデバッグ情報を出力していたため、システムログの中に以下のようなログが現れてしまっている。

I/System.out( 1446): 暗号化文字列取得♪:14bd8763ade879d87ff09155ae8b8ca7
I/System.out( 1446): 復号てすと♪:yuya-baka!

 このログが出力されてしまう際の実際のソースコードは以下のようなものだ。標準出力へ出力を行うprintlnメソッドを利用した、ごく一般的な記述となる。

String encryptedPassword = CryptUtils.getEncryptedPassword();
System.out.println("暗号化文字列取得♪:"+encryptedPassword);
String decryptedPassword = CryptUtils.decryptString(encryptedPassword);
System.out.println("復号てすと♪:"+decryptedPassword);

 作成したアプリケーションをデバッグする方法として、標準出力やログ出力クラス(System.out.printlnやandroid.util.Logクラス)に変数の状態などを出力する方法は比較的広く利用されている。Android SDKでも、システムログを閲覧する機能などが整備されているため、クウもその方法を利用してしまっていた。

 しかしAndroidアプリケーションでは、android.util.Logクラスなどで、デバッグレベルにより出力していた場合(dメソッドによる出力)であっても、デバッグ時だけでなくリリースした際にもログに出力されてしまうことを考慮する必要がある(機種によっては異なる場合があります)。

図2 AndroidSDKを利用した実機のログ閲覧例 図2 AndroidSDKを利用した実機のログ閲覧例(クリックすると拡大します)

 「ログを出力してしまっている」という状態だけであれば、さほど問題がないように聞こえるかもしれない。だがそれは、USBデバッグ接続のような状態のみを想定した場合である。

 しかし実際には、このログ情報は、android.permission.READ_LOGSパーミッションが付与されたAndroidアプリケーションから読み込みが可能であるため注意が必要だ。ここでいうパーミッションとは、ユーザーがAndroidアプリケーションをインストールする際に画面上で確認できる、動作許可のようなものである。

図3 システムログを読み込むAndroidアプリケーションのパーミッション表示 図3 システムログを読み込むAndroidアプリケーションのパーミッション表示

 android.permission.READ_LOGSパーミッションが付与されている場合、ユーザーがこのパーミッションを利用するアプリケーションをインストールする際の表示には、「システムログファイルの読み取り」という程度にしか書かれていない。このため、ユーザーが内容を理解せずにインストールしてしまう可能性が高い。もちろん、システムのリソース管理などの機能を持ったアプリケーションであれば、このパーミッションは付与されていても違和感がないものとなる。

 ただしこのパーミッションが付与されてしまった場合には、該当のAndroidアプリケーションでは、以下のようなコードにより、USBデバッグで接続した際のlogcatコマンドの結果と同じものを取得することが可能となる。

try {
    Process process = Runtime.getRuntime().exec("logcat");
    BufferedReader reader = new BufferedReader(
        new InputStreamReader(process.getInputStream()));
    String line = reader.readLine();
    while(line != null) {
        //取得したログに対する処理
    }
} catch (Exception e) {
    // エラー処理
}

 このように、作成したAndroidアプリケーションに、パスワードなどの重要な情報をログに出力してしまう挙動があった場合、システムログを通じてそれが漏えいしてしまう可能性がある。

Copyright © ITmedia, Inc. All Rights Reserved.

RSSについて

アイティメディアIDについて

メールマガジン登録

@ITのメールマガジンは、 もちろん、すべて無料です。ぜひメールマガジンをご購読ください。