OWASP 類別:MASVS-CODE:程式碼品質
總覽
使用 PendingIntent.getCreator*()
或 PendingIntent.getTarget*()
判斷是否信任 PendingIntent 的傳送者,會造成遭到濫用的風險。
PendingIntent.getCreator*()
或
PendingIntent.getTarget*()
會傳回 PendingIntent 的建立者,但這不一定與傳送者相符。建立者可能值得信任,但絕不應信任傳送者,因為傳送者可能是惡意應用程式,透過各種機制取得其他應用程式的 PendingIntent,例如:
- 來自
NotificationListenerService
- 屬於有安全漏洞應用程式的合法用途。
合法使用 PendingIntent.getCreator*()
或 PendingIntent.getTarget*()
的例子是顯示 PendingIntent 將啟動的應用程式圖示。
影響
如果您查詢 (並信任) 建立者,因而信任 PendingIntent 的傳送者,可能會導致安全漏洞。如果應用程式根據 PendingIntent 的建立者信任該 Intent 的傳送者,然後分享其驗證或授權邏輯,那麼每當 PendingIntent 的傳送者是惡意應用程式時,就會導致驗證遭略過,或甚至根據無效、不受信任的輸入內容執行遠端程式碼,具體情況取決於易受攻擊的應用程式程式碼實作方式。
因應措施
區分傳送者和建立者
接收 PendingIntent 時執行的任何驗證或授權邏輯,都不得根據對 PendingIntent 建立者的假設,該建立者是使用 PendingIntent.getCreator*()
或 PendingIntent.getTarget*()
識別。
使用其他方式驗證呼叫端
如要驗證呼叫端,請使用 Service 或 ContentProvider,而非 PendingIntent。這兩者都允許在分派傳入的 IPC 時,使用 Binder.getCallingUid() 擷取呼叫端 UID。稍後可以使用 PackageManager.getPackagesForUid() 查詢 UID。
從 API 級別 34 開始,您也可以使用 BroadcastReceiver.getSentFromUid() 或 BroadcastReceiver.getSentFromPackage(),前提是傳送者在廣播期間使用 BroadcastOptions.isShareIdentityEnabled() 選擇分享身分。
您應一律檢查呼叫套件是否具有預期簽章,因為側載套件的套件名稱可能與 Play 商店的套件名稱重疊。