OWASP カテゴリ: MASVS-CODE: コード品質
概要
PendingIntent.getCreator*()
または PendingIntent.getTarget*()
を使用して PendingIntent の送信者を信頼するかどうかを判断すると、悪用のリスクが生じます。
PendingIntent.getCreator*()
または PendingIntent.getTarget*()
は PendingIntent の作成者を返しますが、これは送信者と常に一致するとは限りません。作成者は信頼できるかもしれませんが、送信者は決して信頼すべきではありません。送信者は、さまざまなメカニズムを使用して別のアプリの PendingIntent を取得した悪意のあるアプリである可能性があるためです。たとえば、次のような場合です。
NotificationListenerService
から- 脆弱なアプリの一部である正当なユースケース。
PendingIntent.getCreator*()
または PendingIntent.getTarget*()
の正当な使用例としては、PendingIntent によって起動されるアプリのアイコンを表示することが挙げられます。
影響
作成者をクエリして(信頼している)ため、PendingIntent の送信者を信頼すると、脆弱性につながる可能性があります。アプリが作成者に基づいて PendingIntent の送信者を信頼し、認証または認可ロジックを共有する場合、PendingIntent の送信者が悪意のあるアプリであるたびに、脆弱なアプリのコードの実装に応じて、無効で信頼できない入力に基づく認証バイパスやリモートコード実行につながる可能性があります。
リスクの軽減
送信者と作成者を区別する
PendingIntent の受信時に実行される認証または認可ロジックは、PendingIntent.getCreator*()
または PendingIntent.getTarget*()
を使用して特定された PendingIntent の作成者に関する想定に基づいてはなりません。
別の方法で呼び出し元を検証する
呼び出し元を認証する必要がある場合は、PendingIntent ではなく Service または ContentProvider を使用する必要があります。どちらも、受信 IPC をディスパッチするコンテキストで Binder.getCallingUid() を使用して呼び出し元 UID を取得できます。UID は、後で PackageManager.getPackagesForUid() を使用してクエリできます。
API レベル 34 以降では、送信者が BroadcastOptions.isShareIdentityEnabled() を使用してブロードキャスト中に ID の共有を有効にしている場合、BroadcastReceiver.getSentFromUid() または BroadcastReceiver.getSentFromPackage() を使用する方法もあります。
サイドローディングされたパッケージは Play ストアのパッケージ名と重複する可能性があるため、呼び出し元のパッケージに想定される署名があるかどうかを常に確認する必要があります。