این سند توضیح میدهد که چگونه توسعهدهندگان برنامه میتوانند از ویژگیهای امنیتی ارائه شده توسط اندروید برای تعریف مجوزهای خود استفاده کنند. با تعریف مجوزهای سفارشی، یک برنامه میتواند منابع و قابلیتهای خود را با سایر برنامهها به اشتراک بگذارد. برای اطلاعات بیشتر در مورد مجوزها، به نمای کلی مجوزها مراجعه کنید.
پیشینه
اندروید یک سیستم عامل با تفکیک امتیاز است که در آن هر برنامه با یک هویت سیستمی مجزا (شناسه کاربری و شناسه گروه لینوکس) اجرا میشود. بخشهایی از سیستم نیز به هویتهای مجزا تفکیک شدهاند. در نتیجه، لینوکس برنامهها را از یکدیگر و از سیستم جدا میکند.
برنامهها میتوانند با تعریف مجوزهایی که سایر برنامهها میتوانند درخواست کنند، عملکرد خود را در معرض دید سایر برنامهها قرار دهند. همچنین میتوانند مجوزهایی را تعریف کنند که به طور خودکار در دسترس سایر برنامههایی که با همان گواهی امضا شدهاند، قرار گیرد.
امضای برنامه
همه APKها باید با گواهینامهای امضا شوند که کلید خصوصی آن نزد توسعهدهندهشان است. نیازی نیست گواهینامه توسط یک مرجع صدور گواهینامه امضا شده باشد. استفاده از گواهینامههای خودامضا برای برنامههای اندروید مجاز و معمول است. هدف از گواهینامهها در اندروید، تشخیص نویسندگان برنامه است. این به سیستم اجازه میدهد تا به برنامهها دسترسی به مجوزهای سطح امضا را اعطا یا رد کند و درخواست یک برنامه برای دریافت هویت لینوکس مشابه برنامه دیگر را بپذیرد یا رد کند.
اعطای مجوزهای امضا پس از زمان تولید دستگاه
از اندروید ۱۲ (سطح API 31)، ویژگی knownCerts برای مجوزهای سطح امضا به شما امکان میدهد در زمان اعلان، به خلاصهای از گواهیهای امضای شناختهشده مراجعه کنید.
شما میتوانید ویژگی knownCerts را اعلام کنید و از پرچم knownSigner در ویژگی protectionLevel برنامه خود برای یک مجوز سطح امضای خاص استفاده کنید. سپس، اگر هر امضاکنندهای در دودمان امضای برنامه درخواستکننده، از جمله امضاکننده فعلی، با یکی از خلاصههایی که با مجوز در ویژگی knownCerts اعلام شده است، مطابقت داشته باشد، سیستم آن مجوز را به برنامه درخواستکننده اعطا میکند.
پرچم knownSigner به دستگاهها و برنامهها اجازه میدهد تا مجوزهای امضا را به برنامههای دیگر اعطا کنند، بدون اینکه لازم باشد برنامهها را در زمان تولید و ارسال دستگاه امضا کنند.
شناسههای کاربری و دسترسی به فایلها
در زمان نصب، اندروید به هر بسته یک شناسه کاربری لینوکس مجزا میدهد. این شناسه در طول عمر بسته روی آن دستگاه ثابت میماند. در یک دستگاه دیگر، همان بسته ممکن است یک شناسه کاربری (UID) متفاوت داشته باشد - نکته مهم این است که هر بسته در یک دستگاه خاص یک شناسه کاربری مجزا دارد.
از آنجا که اجرای امنیت در سطح فرآیند اتفاق میافتد، کد هیچ دو بستهای معمولاً نمیتواند در یک فرآیند اجرا شود، زیرا آنها باید به عنوان کاربران مختلف لینوکس اجرا شوند.
هر دادهای که توسط یک برنامه ذخیره میشود، شناسه کاربری آن برنامه را دریافت میکند و معمولاً برای سایر بستهها قابل دسترسی نیست.
برای اطلاعات بیشتر در مورد مدل امنیتی اندروید، به «مروری بر امنیت اندروید» مراجعه کنید.
تعریف و اعمال مجوزها
برای اعمال مجوزهای خودتان، ابتدا باید آنها را در AndroidManifest.xml خود با استفاده از یک یا چند عنصر <permission> اعلان کنید.
قرارداد نامگذاری
سیستم اجازه نمیدهد چندین بسته، مجوزی با نام یکسان اعلام کنند، مگر اینکه همه بستهها با گواهی یکسان امضا شده باشند. اگر یک بسته مجوزی را اعلام کند، سیستم همچنین به کاربر اجازه نصب بستههای دیگر با نام مجوز یکسان را نمیدهد، مگر اینکه آن بستهها با گواهی مشابه بسته اول امضا شده باشند.
توصیه میکنیم مجوزها را با نام بسته برنامه، با استفاده از نامگذاری به سبک دامنه معکوس، پیشوند کنید و به دنبال آن .permission. و سپس توضیحی از قابلیتی که مجوز نشان میدهد، در SNAKE_CASE بالایی قرار دهید. به عنوان مثال، com.example.myapp.permission.ENGAGE_HYPERSPACE .
پیروی از این توصیه از تصادم نامگذاری جلوگیری میکند و به شناسایی واضح مالک و هدف یک مجوز سفارشی کمک میکند.
مثال
برای مثال، برنامهای که نیاز دارد کنترل کند کدام برنامههای دیگر میتوانند یکی از فعالیتهایش را شروع کنند، میتواند مجوز این عملیات را به صورت زیر اعلام کند:
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.myapp" > <permission android:name="com.example.myapp.permission.DEADLY_ACTIVITY" android:label="@string/permlab_deadlyActivity" android:description="@string/permdesc_deadlyActivity" android:permissionGroup="android.permission-group.COST_MONEY" android:protectionLevel="dangerous" /> ... </manifest>
ویژگی protectionLevel الزامی است و به سیستم میگوید که چگونه کاربران را از برنامههایی که به این مجوز نیاز دارند یا برنامههایی که میتوانند این مجوز را داشته باشند، مطلع کند، همانطور که در مستندات مرتبط توضیح داده شده است.
ویژگی android:permissionGroup اختیاری است و فقط برای کمک به سیستم در نمایش مجوزها به کاربر استفاده میشود. در بیشتر موارد، شما این را روی یک گروه سیستمی استاندارد (که در android.Manifest.permission_group فهرست شده است) تنظیم میکنید، اگرچه میتوانید خودتان یک گروه تعریف کنید، همانطور که در بخش بعدی توضیح داده شده است. ما استفاده از یک گروه موجود را توصیه میکنیم، زیرا این کار رابط کاربری مجوز نشان داده شده به کاربر را ساده میکند.
شما باید برای مجوز، هم برچسب و هم توضیح ارائه دهید. اینها منابع رشتهای هستند که کاربر میتواند هنگام مشاهده لیستی از مجوزها ( android:label ) یا جزئیات مربوط به یک مجوز واحد ( android:description ) آنها را ببیند. برچسب کوتاه است: چند کلمه که بخش کلیدی عملکرد محافظتشده توسط مجوز را توصیف میکند. توضیح شامل چند جمله است که توصیف میکند مجوز به دارنده آن چه کاری را اجازه میدهد. قرارداد ما این است که یک توضیح دو جملهای داشته باشیم که در آن جمله اول مجوز را توصیف میکند و جمله دوم به کاربر در مورد انواع مشکلاتی که در صورت اعطای مجوز به یک برنامه ممکن است پیش بیاید، هشدار میدهد.
در اینجا مثالی از برچسب و توضیحات مربوط به مجوز CALL_PHONE آورده شده است:
<string name="permlab_callPhone">directly call phone numbers</string> <string name="permdesc_callPhone">Allows the app to call non-emergency phone numbers without your intervention. Malicious apps may cause unexpected calls on your phone bill.</string>
ایجاد یک گروه مجوز
همانطور که در بخش قبلی نشان داده شد، میتوانید از ویژگی android:permissionGroup برای کمک به سیستم در توصیف مجوزها به کاربر استفاده کنید. در بیشتر موارد، این را روی یک گروه سیستمی استاندارد (که در android.Manifest.permission_group ذکر شده است) تنظیم میکنید، اما میتوانید گروه خودتان را نیز با <permission-group> تعریف کنید.
عنصر <permission-group> برچسبی را برای مجموعهای از مجوزها تعریف میکند - چه آنهایی که در مانیفست با عناصر <permission> اعلام شدهاند و چه آنهایی که در جای دیگری اعلام شدهاند. این فقط بر نحوه گروهبندی مجوزها هنگام ارائه به کاربر تأثیر میگذارد. عنصر <permission-group> مجوزهای متعلق به گروه را مشخص نمیکند، اما به گروه یک نام میدهد.
شما میتوانید با اختصاص نام گروه به ویژگی permissionGroup عنصر <permission> ، یک مجوز در گروه قرار دهید.
عنصر <permission-tree> یک فضای نام برای گروهی از مجوزها که در کد تعریف شدهاند، اعلام میکند.
توصیههای مجوز سفارشی
شما میتوانید با تعریف عناصر <uses-permission> مجوزهای سفارشی را برای برنامههای خود تعریف کنید و از برنامههای دیگر مجوزهای سفارشی درخواست کنید. با این حال، به دقت ارزیابی کنید که آیا انجام این کار ضروری است یا خیر.
- اگر در حال طراحی مجموعهای از برنامهها هستید که عملکردها را در معرض یکدیگر قرار میدهند، سعی کنید برنامهها را طوری طراحی کنید که هر مجوز فقط یک بار تعریف شود. اگر همه برنامهها با یک گواهی امضا نشدهاند، باید این کار را انجام دهید. حتی اگر همه برنامهها با یک گواهی امضا شده باشند، بهترین روش این است که هر مجوز را فقط یک بار تعریف کنید.
- اگر این قابلیت فقط برای برنامههایی که با امضای مشابه برنامهی ارائهدهنده امضا شدهاند، در دسترس باشد، میتوانید با استفاده از بررسی امضا، از تعریف مجوزهای سفارشی جلوگیری کنید. وقتی یکی از برنامههای شما درخواستی را به یکی دیگر از برنامههای شما ارسال میکند، برنامهی دوم میتواند قبل از اجابت درخواست، تأیید کند که هر دو برنامه با گواهی یکسان امضا شدهاند.
اگر مجوز سفارشی ضروری است، در نظر بگیرید که آیا فقط برنامههایی که توسط همان توسعهدهندهای که برنامهی بررسی مجوز را انجام میدهد امضا شدهاند، نیاز به دسترسی به آن دارند یا خیر - مانند هنگام پیادهسازی ارتباطات بینپردازشی امن بین دو برنامه از یک توسعهدهنده. در این صورت، توصیه میکنیم از مجوزهای امضا استفاده کنید. مجوزهای امضا برای کاربر شفاف هستند و از مجوزهای تأیید شده توسط کاربر، که میتواند برای کاربران گیجکننده باشد، جلوگیری میکنند.
ادامه مطلب در مورد:
-
<uses-permission> - مرجع API برای تگ مانیفست که مجوزهای سیستمی مورد نیاز برنامه شما را اعلام میکند.
همچنین ممکن است به موارد زیر علاقه داشته باشید:
- بررسی اجمالی امنیت اندروید
- بحث مفصلی در مورد مدل امنیتی پلتفرم اندروید.