針對匯出的元件具備以權限為基礎的存取權控管

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" />

單一工作端點

按照「關切事項分離」設計原則實作應用程式。每個端點都應只執行一小組具備特定權限的特定工作。這種良好的設計做法也讓開發人員能夠為每個端點套用精細的權限。舉例來說,請避免建立同時提供日曆和聯絡人服務的單一端點。

資源