Android Fragmentインジェクション

外部入力に基づくAndroid Fragmentの生成

説明

外部入力のクラス名をFragment.instantiateなどの動的生成APIへ渡すと、攻撃者が意図しないFragmentを読み込ませる可能性があります。exported Activityで使う場合、権限の低いアプリから内部画面や機密性の高い操作へアクセスされるおそれがあります。

想定される影響

  • 内部Fragmentや設定画面の公開
  • 必要な権限確認を回避した機能へのアクセス
  • 機密データの表示やアプリ状態の変更

対処方法

  1. 外部入力をFragmentのクラス名として直接使わないでください。
  2. 許可したFragment識別子だけを許可リストで対応付けてください。
  3. PreferenceActivityを使う場合、isValidFragmentは明示的に許可した名前だけにtrueを返すようにしてください。許可した画面でもユーザー権限を確認し、不要なActivityの外部公開を制限してください。

例

既存のActivity内部の抜粋です。SettingsFragmentはアプリケーションが定義した許可対象であり、画面へのアクセス権限は別途確認する必要があります。

変更前

java
String fragment = getIntent().getStringExtra("fragment");
Fragment.instantiate(this, fragment);

変更後

java
Map<String, String> allowed = Map.of("settings", SettingsFragment.class.getName());
String fragment = allowed.get(getIntent().getStringExtra("fragment"));
if (fragment != null) {
    Fragment.instantiate(this, fragment);
}

説明:

  • 変更前: 外部のクラス名をFragment.instantiateへ渡すため、exported Activityに意図しないFragmentを読み込ませるおそれがあります。
  • 変更後: 許可した識別子を既知のFragment名へ対応付けます。静的に生成したFragmentインスタンスを使う方法もあります。

参考資料