待處理意圖

OWASP 類別:MASVS-PLATFORM:平台互動

總覽

PendingIntent 會參照系統維護的權杖。應用程式 A 可將 PendingIntent 傳遞至應用程式 B,讓應用程式 B 代表應用程式 A 執行預先定義的動作;無論應用程式 A 是否仍有效,結果都是這樣。

風險:可變動的待處理意圖

PendingIntent 可以變動,這表示應用程式 B 可按照 fillIn() 說明文件中所述的邏輯,更新用於指定動作的內部意圖。換句話說,惡意應用程式可以修改 PendingIntent 的未填入欄位,並允許存取有漏洞應用程式的其他未匯出元件。

影響

此安全漏洞造成的影響取決於應用程式遭鎖定的未匯出功能的實作方式。

因應措施

一般

確保已設定動作、元件和套件,以避免最嚴重的安全漏洞:

Kotlin

val intent = Intent(intentAction)

// Or other component setting APIs e.g. setComponent, setClass
intent.setClassName(packageName, className)

PendingIntent pendingIntent =
    PendingIntent.getActivity(
        context,
        /* requestCode = */ 0,
        intent, /* flags = */ PendingIntent.FLAG_IMMUTABLE
    )

Java

Intent intent = new Intent(intentAction);

// Or other component setting APIs e.g. setComponent, setClass
intent.setClassName(packageName, className);

PendingIntent pendingIntent =
        PendingIntent.getActivity(
            getContext(),
            /* requestCode= */ 0,
            intent, /* flags= */ 0);

標記 IMMUTABLE

如果應用程式指定的是 Android 6 (API 級別 23) 以上版本,請指定可變動性。舉例來說,您可以使用 FLAG_IMMUTABLE 避免惡意應用程式填入未填寫的欄位:

Kotlin

val pendingIntent =
    PendingIntent.getActivity(
        context,
        /* requestCode = */ 0,
        Intent(intentAction),
        PendingIntent.FLAG_IMMUTABLE)

Java

PendingIntent pendingIntent =
        PendingIntent.getActivity(
            getContext(),
            /* requestCode= */ 0,
            new Intent(intentAction),
            PendingIntent.FLAG_IMMUTABLE);

在 Android 11 (API 級別 30) 及以上版本中,您必須指定要變動的欄位,以降低該類型的意外安全漏洞。

資源


風險:重播待處理意圖

除非設定 FLAG_ONE_SHOT 旗標,否則可以重播 PendingIntent。請務必使用 FLAG_ONE_SHOT 以避免重播攻擊 (執行不應重複的操作)。

影響

此安全漏洞造成的影響會因意圖接收端的實作方式而不同。惡意應用程式會利用未設定 FLAG_ONE_SHOT 旗標時所建立的 PendingIntent 來擷取及重複使用意圖,以重複執行只應執行一次的動作。

因應措施

不應多次觸發的待處理意圖應使用 FLAG_ONE_SHOT 標記來避免重播攻擊。

Kotlin

val pendingIntent =
      PendingIntent.getActivity(
          context,
          /* requestCode = */ 0,
          Intent(intentAction),
          PendingIntent.FLAG_IMMUTABLE or PendingIntent.FLAG_ONE_SHOT)

Java

PendingIntent pendingIntent =
        PendingIntent.getActivity(
            getContext(),
            /* requestCode= */ 0,
            new Intent(intentAction),
            PendingIntent.FLAG_IMMUTABLE | PendingIntent.FLAG_ONE_SHOT);

資源


資源