OWASP 類別: MASVS-PLATFORM:平台互動
總覽
Android 權限是應用程式資訊清單中聲明的字串 ID,用於要求存取受限資料或動作,並由 Android 架構在執行階段強制執行。
Android 權限等級會指出與權限相關的潛在風險:
- 一般:低風險權限,會在安裝時自動授予
- 危險:高風險權限,可能允許存取私密使用者資料,因此必須在執行階段取得使用者明確核准
- 簽章:僅授予使用與宣告權限的應用程式相同的憑證簽署的應用程式,通常用於系統應用程式或相同開發人員的應用程式之間的互動
當應用程式的元件 (例如活動、接收器、內容供應器或服務) 符合下列所有條件時,就會發生與權限控管相關的安全性弱點:
- 元件未與
Manifest中的任何android:permission建立關聯; - 元件執行敏感工作,且使用者已核准該工作所需的權限;
- 元件已匯出;
- 這個元件不會執行任何手動 (資訊清單或程式碼層級) 權限檢查;
發生這種情況時,惡意應用程式可能會濫用有安全漏洞元件的權限,將有安全漏洞應用程式的權限代理給惡意應用程式,進而執行敏感操作。
影響
匯出有安全漏洞的元件可用於存取機密資源或執行敏感操作。這種不當行為的影響取決於有安全漏洞的元件及其權限。
因應措施
要求執行私密資訊相關工作時必須具備權限
匯出具有私密權限的元件時,請對任何傳入的要求套用相同的權限。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 Access to app protected components from the Oversecured blog
- 內容供應商最佳做法
- 執行階段 (危險) 權限
- 關注點分離設計原則
- Android 權限說明文件
- Android 廣播接收器安全提示
- Android 服務安全性提示
- Android 12 (API 31) 預設將「exported」設為「false」
- Lint 檢查:不應匯出 PreferenceActivity
- Lint 檢查:匯出的接收器不需要權限
- Lint 檢查:匯出的服務不需要權限