針對匯出的元件具備以權限為基礎的存取權控管
透過集合功能整理內容
你可以依據偏好儲存及分類內容。
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" />
單一工作端點
按照「關切事項分離」設計原則實作應用程式。每個端點都應只執行一小組具備特定權限的特定工作。這種良好的設計做法也讓開發人員能夠為每個端點套用精細的權限。舉例來說,請避免建立同時提供日曆和聯絡人服務的單一端點。
資源
這個頁面中的內容和程式碼範例均受《內容授權》中的授權所規範。Java 與 OpenJDK 是 Oracle 和/或其關係企業的商標或註冊商標。
上次更新時間:2025-07-26 (世界標準時間)。
[[["容易理解","easyToUnderstand","thumb-up"],["確實解決了我的問題","solvedMyProblem","thumb-up"],["其他","otherUp","thumb-up"]],[["缺少我需要的資訊","missingTheInformationINeed","thumb-down"],["過於複雜/步驟過多","tooComplicatedTooManySteps","thumb-down"],["過時","outOfDate","thumb-down"],["翻譯問題","translationIssue","thumb-down"],["示例/程式碼問題","samplesCodeIssue","thumb-down"],["其他","otherDown","thumb-down"]],["上次更新時間:2025-07-26 (世界標準時間)。"],[],[],null,["# Permission-based access control to exported components\n\n\u003cbr /\u003e\n\n**OWASP category:** [MASVS-PLATFORM: Platform Interaction](https://mas.owasp.org/MASVS/09-MASVS-PLATFORM)\n\nOverview\n--------\n\nAn Android permission is a string identifier declared in the app's manifest to\nrequest access to restricted data or actions, enforced at runtime by the Android\nframework.\n\n[Android permission levels](/guide/topics/manifest/permission-element#plevel) indicate the potential risk associated with the\npermission:\n\n- **Normal**: Low-risk permissions, automatically granted at install time\n- **Dangerous**: High-risk permissions that could allow access to sensitive user data, requiring explicit user approval at runtime\n- **Signature**: Granted only to apps signed with the same certificate as the app declaring the permission, typically used for system apps or interactions between apps from the same developer\n\nVulnerabilities related to permission-based access controls occur when an app's\ncomponent (such as [activity](/reference/android/app/Activity), [receiver](/privacy-and-security/security-tips#broadcast-receivers), [content provider](/privacy-and-security/security-tips#content-providers), or\n[service](/privacy-and-security/security-tips#services)) meets all of the following criteria:\n\n- The component is not associated with any `android:permission` in the `Manifest`;\n- The component performs a sensitive task for which a permission exists that the user has already approved;\n- The component is exported;\n- The component does not perform any manual (manifest or code-level) permission checks;\n\nWhen this happens, a malicious app can perform sensitive actions by abusing the\nprivileges of the vulnerable component, proxying the vulnerable app's privileges\nto the malicious app.\n\nImpact\n------\n\nExporting vulnerable components can be used to gain access to sensitive\nresources or to perform sensitive actions. The impact of this unwanted behavior\ndepends on the context of the vulnerable component and its privileges.\n\nMitigations\n-----------\n\n### Require permissions for sensitive tasks\n\nWhen exporting a component with sensitive permissions, require those same\npermissions for any incoming request. The Android Studio IDE has lint checks for\n[receivers](https://googlesamples.github.io/android-custom-lint-rules/checks/ExportedReceiver.md.html) and [services](https://googlesamples.github.io/android-custom-lint-rules/checks/ExportedService.md.html) to spot this\nvulnerability and recommend requiring the appropriate permissions.\n\nDevelopers can require permissions for incoming requests either by declaring\nthem in the `Manifest` file or at code-level when implementing the service, as\nin the following examples. \n\n### Xml\n\n \u003cmanifest ...\u003e\n \u003cuses-permission android:name=\"android.permission.READ_CONTACTS\" /\u003e\n\n \u003capplication ...\u003e\n \u003cservice android:name=\".MyExportService\"\n android:exported=\"true\"\n android:permission=\"android.permission.READ_CONTACTS\" /\u003e\n\n \u003c/application\u003e\n \u003c/manifest\u003e\n\n### Kotlin\n\n class MyExportService : Service() {\n\n private val binder = MyExportBinder()\n\n override fun onBind(intent: Intent): IBinder? {\n // Enforce calling app has the required permission\n enforceCallingPermission(Manifest.permission.READ_CONTACTS, \"Calling app doesn't have READ_CONTACTS permission.\")\n // Permission is enforced, proceed with export logic\n return binder\n }\n\n // Inner class for your Binder implementation\n private inner class MyExportBinder : Binder() {\n // Permission is enforced, proceed with export logic\n }\n }\n\n### Java\n\n public class MyExportService extends Service {\n\n @Override\n public IBinder onBind(Intent intent) {\n // Enforce calling app has the required permission\n enforceCallingPermission(Manifest.permission.READ_CONTACTS, \"Calling app doesn't have READ_CONTACTS permission.\");\n\n return binder;\n\n }\n\n // Inner class for your Binder implementation\n private class MyExportBinder extends Binder {\n // Permission is enforced, proceed with export logic\n\n }\n }\n\n### Don't export the component\n\nAvoid exporting components with access to sensitive resources unless absolutely\nnecessary. You can achieve this by setting the `android:exported` in the\n`Manifest` file to `false` for your component. From [API level 31](/about/versions/12/behavior-changes-12#exported) and\nbeyond, this attribute is set to `false`by default. \n\n### Xml\n\n \u003cactivity\n android:name=\".MyActivity\"\n android:exported=\"false\"/\u003e\n\n### Apply signature-based permissions\n\nWhen sharing data between two apps that you control or own, use signature-based\npermissions. These permissions don't require user confirmation and, instead,\ncheck that the apps accessing the data is signed using the same signing key.\nThis setup offers a more streamlined, secure user experience. If you declare\ncustom permissions do consider the [corresponding security guidelines](https://developer.android.com/privacy-and-security/risks). \n\n### Xml\n\n \u003cmanifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\n package=\"com.example.myapp\"\u003e\n \u003cpermission android:name=\"my_custom_permission_name\"\n android:protectionLevel=\"signature\" /\u003e\n\n### Single-task endpoints\n\nImplement your app by following the [Separation of Concerns](/topic/architecture#separation-of-concerns) design\nprinciple. Each endpoint should only perform a small set of specific tasks with\nspecific privileges. This good design practice also allows the developer to\napply granular permissions for each endpoint. For example, avoid creating a\nsingle endpoint that serves both calendar and contacts.\n\nResources\n---------\n\n- [Android Access to app protected components from the Oversecured blog](https://blog.oversecured.com/Android-Access-to-app-protected-components/)\n- [Content Provider Best Practices](/privacy-and-security/security-tips#content-providers)\n- [Runtime (Dangerous) Permissions](/guide/topics/permissions/overview#runtime)\n- [Separation of Concerns design principle](/topic/architecture#separation-of-concerns)\n- [Android permissions documentation](/guide/topics/manifest/permission-element#plevel)\n- [Android broadcast receivers security tips](/privacy-and-security/security-tips#broadcast-receivers)\n- [Android services security tips](/privacy-and-security/security-tips#services)\n- [Android 12 (API 31) exported default set to \"false\"](/about/versions/12/behavior-changes-12#exported)\n- [Lint Check: Exported PreferenceActivity shouldn't be exported](https://googlesamples.github.io/android-custom-lint-rules/checks/ExportedPreferenceActivity.md.html)\n- [Lint Check: Exported Receiver doesn't require permission](https://googlesamples.github.io/android-custom-lint-rules/checks/ExportedReceiver.md.html)\n- [Lint Check: Exported Service doesn't require permission](https://googlesamples.github.io/android-custom-lint-rules/checks/ExportedService.md.html)"]]