Implicit PendingIntent
暗黙的な PendingIntent
説明
Android アプリケーションにおける暗黙的インテント (implicit intent) の脆弱性、特に暗黙的な PendingIntent は、重大なセキュリティリスクをもたらします。これらの脆弱性は、開発者が明示的にターゲットコンポーネントを指定せずに暗黙的インテントを使用し、インテントフィルターに依存して受信者を決定する場合に発生します。攻撃者は、暗黙的インテントの条件に一致する悪意のあるインテントを送信することでこれを悪用し、不正なアクションやアクセスにつながる可能性があります。一般的な問題には、偽のインテントが作成されるインテントのなりすまし (intent spoofing) や、悪意のあるアプリケーションが暗黙的インテントの条件に一致するインテントフィルターを登録する可能性が含まれます。権限の昇格、データの露出、および安全でないコンポーネントも懸念事項です。暗黙的な PendingIntent から生じる可能性のあるセキュリティ問題のリストを以下に示します。
- インテントのなりすまし (Intent Spoofing):
-
攻撃者は、暗黙的な
PendingIntentの条件に一致する偽のインテントを送信しようとする場合があります。これにより、アプリケーションで意図しないアクションが実行され、セキュリティ侵害を引き起こす可能性があります。 -
悪意のあるインテントフィルター:
-
インテントフィルターが慎重に構成されていない場合、悪意のあるアプリケーションが暗黙的な
PendingIntentの条件に一致するインテントフィルターを登録する可能性があります。これにより、意図しないコンポーネントによって機密性の高いアクションが実行される結果となります。 -
権限の昇格:
-
ターゲットコンポーネントが特定の権限を必要とする場合、暗黙的な
PendingIntentが権限の昇格につながる可能性があります。攻撃者はこれを悪用して、より高い権限を必要とするアクションをトリガーし、不正アクセスにつながる可能性があります。 -
データの露出:
-
機密データが暗黙的な
PendingIntentを通じて渡された場合、インテントが傍受されたり改ざんされたりすると、データが露出するリスクがあります。開発者は、インテントを介して送信されるデータの適切な暗号化と検証を保証する必要があります。 -
Broadcast Receiver の動的登録:
-
Broadcast Receiver をトリガーする暗黙的な
PendingIntentは、レシーバーが動的に登録できる場合、攻撃の影響を受けやすい可能性があります。攻撃者は独自のレシーバーを登録してブロードキャストを傍受し、悪意のあるアクションを実行する可能性があります。 -
安全でないコンポーネント:
-
暗黙的な
PendingIntentによって指定されたターゲットコンポーネント (Activity、Service、Broadcast Receiver) が適切に保護されていない場合、権限の昇格やデータの改ざんなど、さまざまな攻撃に対して脆弱になる可能性があります。 -
信頼できない入力の使用:
-
暗黙的な
PendingIntentに、外部ソースから受信したデータなどの信頼できない入力の使用が含まれている場合、インジェクション攻撃などの脆弱性が生じる可能性があります。このようなセキュリティリスクを防ぐために、入力を検証およびサニタイズしてください。 -
保護されていないエクストラ (Extras):
-
適切な保護なしに、暗黙的な
PendingIntentのエクストラを通じて機密情報を渡すと、データの漏洩につながる可能性があります。開発者は、エクストラにどのような情報が含まれるかについて注意し、それが適切に保護されていることを確認する必要があります。 -
広すぎるインテントフィルター:
-
インテントフィルターが広すぎる場合、意図しないコンポーネントと一致する可能性があり、攻撃対象領域が拡大し、攻撃者が意図していなかったアクションをトリガーできる可能性があります。
-
呼び出し元の ID の確認の失敗:
- 暗黙的な
PendingIntentによって起動されたコンポーネントは、不正アクセスを防ぐために呼び出し元の ID を検証する必要があります。そうしないと、セキュリティの脆弱性が生じる可能性があります。
- 暗黙的な
import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
public class YourActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Create an implicit base Intent and wrap it in a PendingIntent
Intent base = new Intent("ACTION_FOO");
base.setPackage("some_package");
PendingIntent pi = PendingIntent.getService(this, 0, base, 0);
}
}
推奨事項
開発者は、以下のいずれか(さらに言えば、すべて)を適用することで、この脆弱性に対処できます。
- ベースインテントの action、package、および component フィールドが設定されていることを確認する(明示的インテント)。
PendingIntentが信頼できるコンポーネントにのみ配信されるようにする。FLAG_IMMUTABLE(SDK 23 で追加) を使用してPendingIntentsを作成する。これにより、PendingIntentを受け取るアプリケーションが未入力のプロパティを埋めることを防ぎます。アプリが SDK 22 以前を実行しているデバイスでも実行される場合は、開発者が以前のオプションを適用しつつ、次のパターンでPendingIntentの作成を強化することをお勧めします。- インテントに含まれるデータに注意する。
- 不要になった
PendingIntentsはキャンセルする。 - Android の最新のセキュリティプラクティスでアプリを常に最新の状態に保つ。
import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
public class YourActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if (android.os.Build.VERSION.SDK_INT >= 23) {
// Create a PendingIntent using FLAG_IMMUTABLE
Intent base = new Intent("ACTION_FOO");
base.setPackage("some_package");
PendingIntent pi = PendingIntent.getService(this, 0, base, PendingIntent.FLAG_IMMUTABLE);
} else {
Intent base = new Intent("ACTION_FOO");
base.setPackage("some_package");
PendingIntent pi = PendingIntent.getService(this, 0, base, 0);
}
}
}
リンク
基準
- OWASP_MASVS_L1:
- MSTG_PLATFORM_2
- OWASP_MASVS_L2:
- MSTG_PLATFORM_2
- PCI_STANDARDS:
- REQ_2_2
- REQ_6_2
- REQ_6_3
- REQ_11_3
- OWASP_MASVS_v2_1:
- MASVS_CODE_4
- SOC2_CONTROLS:
- CC_2_1
- CC_4_1
- CC_7_1
- CC_7_2
- CC_7_4
- CC_7_5
- CC_9_1
- HIPAA_CONTROLS:
- SECURITY221
- SECURITY212
- SECURITY213