การควบคุมการเข้าถึงตามสิทธิ์เข้าถึงคอมโพเนนต์ที่ส่งออก
จัดทุกอย่างให้เป็นระเบียบอยู่เสมอด้วยคอลเล็กชัน
บันทึกและจัดหมวดหมู่เนื้อหาตามค่ากำหนดของคุณ
หมวดหมู่ OWASP: MASVS-PLATFORM: การโต้ตอบระหว่างแพลตฟอร์ม
ภาพรวม
สิทธิ์ Android คือตัวระบุสตริงที่ประกาศในไฟล์ Manifest ของแอปเพื่อขอสิทธิ์เข้าถึงข้อมูลที่จํากัดหรือการดำเนินการ ซึ่งเฟรมเวิร์ก Android จะบังคับใช้ขณะรันไทม์
ระดับสิทธิ์ของ Android บ่งบอกถึงความเสี่ยงที่อาจเกิดขึ้นซึ่งเชื่อมโยงกับสิทธิ์
- ปกติ: สิทธิ์ที่มีความเสี่ยงต่ำ ซึ่งจะมอบให้โดยอัตโนมัติ ณ เวลาติดตั้ง
- อันตราย: สิทธิ์ที่มีความเสี่ยงสูงซึ่งอาจอนุญาตให้เข้าถึงข้อมูลที่ละเอียดอ่อนของผู้ใช้ ซึ่งต้องได้รับการอนุมัติอย่างชัดแจ้งจากผู้ใช้ขณะรันไทม์
- ลายเซ็น: ให้สิทธิ์แก่แอปที่ลงนามด้วยใบรับรองเดียวกับแอปที่ประกาศสิทธิ์เท่านั้น โดยปกติจะใช้สำหรับแอประบบหรือการโต้ตอบระหว่างแอปจากนักพัฒนาแอปรายเดียวกัน
ช่องโหว่ที่เกี่ยวข้องกับการควบคุมการเข้าถึงตามสิทธิ์จะเกิดขึ้นเมื่อคอมโพเนนต์ของแอป (เช่น กิจกรรม รีซีฟเวอร์ ผู้ให้บริการเนื้อหา หรือบริการ) มีคุณสมบัติตรงตามเกณฑ์ต่อไปนี้ทั้งหมด
- คอมโพเนนต์ไม่ได้เชื่อมโยงกับ
android:permission
ใน Manifest
- คอมโพเนนต์ทำงานที่มีความละเอียดอ่อนซึ่งผู้ใช้อนุมัติไว้อยู่แล้ว
- ระบบส่งออกคอมโพเนนต์
- คอมโพเนนต์ไม่ตรวจสอบสิทธิ์ด้วยตนเอง (ระดับไฟล์ Manifest หรือโค้ด)
ในกรณีนี้ แอปที่เป็นอันตรายจะดําเนินการที่มีความละเอียดอ่อนได้โดยการละเมิดสิทธิ์ของคอมโพเนนต์ที่มีช่องโหว่ โดยทำหน้าที่เป็นพร็อกซีสําหรับสิทธิ์ของแอปที่มีช่องโหว่ให้กับแอปที่เป็นอันตราย
ผลกระทบ
การส่งออกคอมโพเนนต์ที่มีช่องโหว่อาจนำไปใช้เพื่อเข้าถึงทรัพยากรที่มีความละเอียดอ่อนหรือดำเนินการที่มีความละเอียดอ่อนได้ ผลกระทบของลักษณะการทำงานที่ไม่พึงประสงค์นี้ขึ้นอยู่กับบริบทของคอมโพเนนต์ที่มีช่องโหว่และสิทธิ์ของคอมโพเนนต์
การลดปัญหา
ต้องการสิทธิ์สำหรับงานที่มีความละเอียดอ่อน
เมื่อส่งออกคอมโพเนนต์ที่มีสิทธิ์ที่ละเอียดอ่อน ต้องใช้สิทธิ์เดียวกันนั้นสำหรับคำขอที่เข้ามาใหม่ IDE ของ Android Studio มีการตรวจสอบ 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
}
}
ไม่ส่งออกคอมโพเนนต์
หลีกเลี่ยงการส่งออกคอมโพเนนต์ที่มีสิทธิ์เข้าถึงทรัพยากรที่มีความละเอียดอ่อน เว้นแต่จำเป็นจริงๆ ซึ่งทำได้โดยการตั้งค่า android:exported
ในไฟล์ Manifest
เป็น false
สำหรับคอมโพเนนต์ ตั้งแต่ API ระดับ 31 ขึ้นไป ระบบจะตั้งค่าแอตทริบิวต์นี้เป็น false
โดยค่าเริ่มต้น
Xml
<activity
android:name=".MyActivity"
android:exported="false"/>
ใช้สิทธิ์ตามลายเซ็น
เมื่อแชร์ข้อมูลระหว่างแอป 2 แอปที่คุณควบคุมหรือเป็นเจ้าของ ให้ใช้สิทธิ์ตามลายเซ็น สิทธิ์เหล่านี้ไม่จําเป็นต้องได้รับการยืนยันจากผู้ใช้ แต่ระบบจะตรวจสอบว่าแอปที่เข้าถึงข้อมูลได้รับการลงนามโดยใช้คีย์การรับรองเดียวกันแทน
การตั้งค่านี้ช่วยให้ผู้ใช้ได้รับประสบการณ์การใช้งานที่ปลอดภัยและมีประสิทธิภาพมากขึ้น หากคุณประกาศสิทธิ์ที่กำหนดเอง โปรดพิจารณาหลักเกณฑ์ด้านความปลอดภัยที่เกี่ยวข้อง
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 UTC
[[["เข้าใจง่าย","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 UTC"],[],[],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)"]]