OWASP 類別: MASVS-PLATFORM:平台互動
總覽
Android 權限是應用程式資訊清單中宣告的字串 ID,用於要求存取受限資料或操作的權限,並由 Android 架構在執行階段強制執行。
Android 權限層級:表示權限相關的潛在風險:
- 一般:低風險權限,會在安裝時自動授予
- 危險:高風險權限,可能會允許存取機密使用者資料,需要在執行階段獲得使用者明確核准
- Signature:僅授予使用與宣告權限的應用程式相同憑證簽署的應用程式,通常用於系統應用程式,或相同開發人員的應用程式之間互動
當應用程式元件 (例如 活動、接收器、內容供應器或服務) 符合下列所有條件時,就會發生與權限控管相關的安全漏洞:
- 元件未與
Manifest
中的任何android:permission
建立關聯。 - 元件執行機密工作,且使用者已核准該工作所需的權限。
- 元件已匯出。
- 元件不會執行任何手動 (資訊清單或程式碼層級) 權限檢查;
這種情況發生時,惡意應用程式可能會濫用有安全漏洞元件的權限,透過 Proxy 對惡意應用程式的權限,執行敏感動作。
影響
匯出有安全漏洞的元件,可用於存取機密資源或執行機密動作。這項不當行為的影響取決於有安全漏洞的元件及其權限的背景資訊。
因應措施
要求敏感工作權限
匯出具有機密權限的元件時,對於任何傳入的要求,需要這些相同權限。Android Studio IDE 會針對接收器和服務執行 Lint 檢查,以找出這項安全漏洞,並建議您要求適當的權限。
開發人員可以在實作服務時,在 Manifest
檔案或程式碼層級宣告權限,以便要求傳入要求的權限,如以下範例所示。
Xml
<manifest ...>
<uses-permission android:name="android.permission.READ_CONTACTS" />
<application ...>
<service android:name=".MyExportService"
android:exported="true"
android:permission="android.permission.READ_CONTACTS" />
</application>
</manifest>
Kotlin
class MyExportService : Service() {
private val binder = MyExportBinder()
override fun onBind(intent: Intent): IBinder? {
// Enforce calling app has the required permission
enforceCallingPermission(Manifest.permission.READ_CONTACTS, "Calling app doesn't have READ_CONTACTS permission.")
// Permission is enforced, proceed with export logic
return binder
}
// Inner class for your Binder implementation
private inner class MyExportBinder : Binder() {
// Permission is enforced, proceed with export logic
}
}
Java
public class MyExportService extends Service {
@Override
public IBinder onBind(Intent intent) {
// Enforce calling app has the required permission
enforceCallingPermission(Manifest.permission.READ_CONTACTS, "Calling app doesn't have READ_CONTACTS permission.");
return binder;
}
// Inner class for your Binder implementation
private class MyExportBinder extends Binder {
// Permission is enforced, proceed with export logic
}
}
不要匯出元件
除非絕對必要,否則請避免匯出可存取機密資源的元件。只要在元件的 Manifest
檔案中將 android:exported
設為 false
,即可達到這個效果。在 API 級別 31 之後,此屬性預設為 false
。
XML
<activity
android:name=".MyActivity"
android:exported="false"/>
套用以簽名為基礎的權限
如要在您控管或擁有的兩個應用程式之間共用資料,請使用以簽名為基礎的權限。這些權限不需經過使用者確認,而是檢查存取資料的應用程式是否使用同一組簽名金鑰進行簽署。這項設定可以提供更簡便且安全的使用者體驗。如果您宣告自訂權限,請考量相應的安全性指南。
Xml
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.myapp">
<permission android:name="my_custom_permission_name"
android:protectionLevel="signature" />
單一工作端點
按照「關切事項分離」設計原則實作應用程式。每個端點都應只執行一小組具備特定權限的特定工作。這種良好的設計做法也讓開發人員能夠為每個端點套用精細的權限。舉例來說,請避免建立同時提供日曆和聯絡人服務的單一端點。
資源
- Android 存取應用程式保護元件的權限 (取自 Oversecured 網誌)
- 內容供應商最佳做法
- 執行階段 (危險) 權限
- 關注點分離設計原則
- Android 權限說明文件
- Android 廣播接收器安全性提示
- Android 服務安全性提示
- Android 12 (API 31) 將匯出的預設值設為「false」
- Lint 檢查:不應匯出已匯出的 PreferenceActivity
- Lint 檢查:匯出的接收器不需要權限
- Lint 檢查:匯出的服務不需要權限