サンプルアプリの脆弱性説明

サンプルアプリの脆弱性

サンプルアプリ「08オンライン銀行」に存在している脆弱性について詳しく説明します。
具体的にどのような実装が脆弱性につながっているのか、ソースコードを確認してみましょう。

脆弱性のあるソースコード

プロジェクト OutputLog
ソースファイル MainActivity.java
	public void onClickLogin(View v) {
		// 入力された契約番号とパスワードの取得
		String id = ((EditText) findViewById(R.id.edittextId)).getText().toString();
		String pass = ((EditText) findViewById(R.id.edittextPass)).getText().toString();

		// 未入力項目がある場合はメッセージ表示
		if ("".equals(id) || "".equals(pass)) {
			Toast.makeText(this, "入力内容に不備があります", Toast.LENGTH_LONG).show();
			return;
		}

		// 入力内容をログに出力する
		String log = "ID:" + id + " PASS:" + pass;

		// ▼▼▼脆弱性のあるソースコード▼▼▼
		// ログ出力
		Log.v(getPackageName(), log);
		// ▲▲▲脆弱性のあるソースコード▲▲▲

		Intent intent = new Intent(this, MenuActivity.class);
		
		// URLにトークン情報を設定
		String param = String.format("%s?token=%s", URL_ONLINEBANK, getToken(id ,pass));
				
		// ▼▼▼脆弱性のあるソースコード▼▼▼
		// 情報を明示的Intentに設定
		intent.setData(Uri.parse(param));
		// ▲▲▲脆弱性のあるソースコード▲▲▲

		startActivity(intent);
	}
脆弱性の原因となっている処理は以下の2点です。
  • ログの出力
    アプリ内で出力したログはLogCatに出力されます。LogCatに出力された内容は、Android4.1以前の環境では、READ_LOGS権限があるアプリから読み取ることが可能です。
    本サンプルでは、利用者が入力したID・パスワードをログに出力しています(46行目)。
    そのため、ID・パスワードをREAD_LOGS権限があるアプリから読み取られる可能性があります。
    ログ出力を行うメソッドは複数存在します。例えば以下が挙げられます。
    • android.util.Logクラス
      Log.d(), Log.e(), Log.i(), Log.v(), Log.w()
    • java.lang.Systemクラス
      System.out.println(), System.err.println()

  • Intent#setDataでのデータの受け渡し
    Activityを呼び出す際に、Intent.setData()を使用してデータを設定しています。startActivityメソッドを実行すると、ActivityManagerによってIntentの内容がログに出力されるため、READ_LOGS権限があるアプリから読み取られてしまいます。
    本サンプルでは、接続先のURLにidとパスワードを加えたログイン用の情報をIntentに設定しています(56行目)。
    そのため、ログインに必要な情報の全てをREAD_LOGS権限があるアプリから読み取られてしまう可能性があります。

次は、脆弱性の修正方法について説明します。