開發人員請注意,如果您的應用程式含有 Intent Redirection 安全漏洞,請詳閱本文資訊。
問題說明
您的一或多個應用程式含有 Intent Redirection 問題,可能會有惡意應用程式趁機存取非公開的應用程式元件或檔案。請按照下列詳細步驟修正應用程式的問題。在 Play 管理中心 顯示的修正期限過後,Google Play 會將尚未修復安全漏洞的應用程式下架。
敬請配合
- 登入 Play 管理中心,然後前往「快訊」專區查看受影響的應用程式以及解決這些問題的期限。
- 按照下方標明的步驟更新受影響的應用程式。
- 提交受影響應用程式的更新版本。
我們將再次審查您重新提交的應用程式,過程可能需要數小時。如果應用程式可以通過審查並成功發布,您就不必採取進一步行動。如果應用程式未能通過審查,就無法發布新的版本,而且您將收到電子郵件通知。
其他詳細資訊
使用不受信任的 Intent 啟動元件 (如呼叫 startActivity) 或傳回資料 (如呼叫 setResult) 具有危險,並可能導致惡意應用程式造成以下問題:
- 從您的應用程式中竊取敏感的檔案或系統資料 (例如簡訊)
- 使用中毒的引數啟動應用程式的私人元件
對於不受信任的 Intent,請務必防止您的應用程式在 Intent 未經過驗證或安全處理的情況下呼叫 startActivity、startService、sendBroadcast 或 setResult。
建議您採用下列其中一種做法來防堵這個安全漏洞:
做法 1:將受影響的應用程式元件 (擷取的 Intent 會從中重新導向) 設為不公開。
如果受影響的應用程式元件不需要接收來自其他應用程式的 Intent,您可以在資訊清單中設定 android:exported="false",將該應用程式元件設為不公開。
做法 2:確定擷取的 Intent 來自可信的來源。
您可以使用類似 getCallingActivity 的方法來驗證來源 Activity 是否可信。範例如下:
// 檢查來源 Activity 是否來自可信任的套件
if (getCallingActivity().getPackageName().equals(“known”)) {
Intent intent = getIntent();
// 擷取巢狀 Intent
Intent forward = (Intent) intent.getParcelableExtra(“key”);
// 將巢狀 Intent 重新導向
startActivity(forward);
}
注意:
- 只檢查 getCallingActivity() 是否傳回非空值並不能完全防堵這項安全漏洞,因為惡意應用程式可以為這個函式提供空值。
- 如果您使用的是 Google Play 服務的 SMS Retriever Auth,透過 SEND_PERMISSION 來保護廣播接收器就能確保 Intent 來自 Play 服務。
做法 3:確定要被重新導向的 Intent 是無害的。
請務必驗證被重新導向的 Intent
應用程式可以查詢用來處理 Intent 的元件為何,再使用類似 resolveActivity 的方法進行重新導向。範例如下:
Intent intent = getIntent();
// 擷取巢狀 Intent
Intent forward = (Intent) intent.getParcelableExtra(“key”);
// 取得元件名稱
ComponentName name = forward.resolveActivity(getPackageManager());
// 確認套件名稱和類別名稱正確無誤
if (name.getPackageName().equals(“safe_package”) &&
name.getClassName().equals(“safe_class”)) {
// 將巢狀 Intent 重新導向
startActivity(forward);
}
應用程式可以查詢 Intent 是否使用類似 getFlags 的方法授予 URI 權限。範例如下:
// 擷取巢狀 Intent
Intent forward = (Intent) intent.getParcelableExtra(“key”);
// 取得標記
int flags = forward.getFlags();
// 確認巢狀 Intent 並未授予 URI 權限
if ((flags & Intent.FLAG_GRANT_READ_URI_PERMISSION == 0) &&
(flags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION == 0)) {
// 將巢狀 Intent 重新導向
startActivity(forward);
}
應用程式也可以使用 removeFlags 移除已授予的 URI 權限。範例如下:
// 不受信任的 Intent
Intent intent = getIntent();
// 移除在不受信任的 Intent 中授予的 URI 權限
intent.removeFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
intent.removeFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
// 傳遞不受信任的 Intent
setResult(intent);
瞭解快訊的作用及選擇防範選項
Play 管理中心快訊會回報您的應用程式在何處使用不受信任的 Intent 呼叫 startActivity、startActivityForResult、startService、sendBroadcast 或 setResult。如果想進一步瞭解最適當的預防做法,請追溯並檢查方法呼叫端,找出不受信任 Intent 的來源。舉例來說,如果採用做法 1,請往回追溯記錄,確定要設為不公開的元件為何。
我們很樂意提供協助
如有關於安全漏洞的技術問題,請前往 Stack Overflow 提問並加上「android-security」標記。如需進一步瞭解這個問題的解決步驟,歡迎與開發人員支援團隊聯絡。