اجازه‌های سفارشی

دسته OWASP: MASVS-CODE: کیفیت کد

نمای کلی

خطرات مرتبط با «اجازه‌های سفارشی» زمانی به‌وجود می‌آید که تعریف اجازه‌های سفارشی وجود نداشته باشد یا غلط املایی داشته باشد، یا زمانی که از مشخصه android:protectionLevel مربوطه در «مانیفست» سوءاستفاده شود.

برای مثال، این خطرات می‌تواند با ایجاد اجازه سفارشی با همان نام، اما تعریف‌شده توسط برنامه مخرب و با اعمال سطوح محافظت متفاوت، مورد سوءاستفاده قرار گیرد.

اجازه‌های سفارشی برای فعال کردن هم‌رسانی منابع و قابلیت‌ها با برنامه‌های دیگر طراحی شده‌اند. نمونه‌هایی از استفاده مشروع از اجازه‌های سفارشی می‌تواند موارد زیر باشد:

  • کنترل ارتباط بین‌فرایندی (IPC) بین دو یا چند برنامه
  • دسترسی به سرویس‌های طرف سوم
  • محدود کردن دسترسی به داده‌های هم‌رسانی‌شده برنامه

تأثیر

تأثیر سوءاستفاده از این آسیب‌پذیری این است که یک برنامه مخرب می‌تواند به منابعی که در اصل قرار بوده محافظت شوند دسترسی پیدا کند. پیامدهای این آسیب‌پذیری به منبعی که محافظت می‌شود و اجازه‌های مرتبط با سرویس برنامه اصلی بستگی دارد.

ریسک: غلط املایی در اجازه سفارشی

ممکن است اجازه سفارشی در «مانیفست» اعلام شود، اما به‌دلیل اشتباه تایپی، از اجازه سفارشی متفاوتی برای محافظت از مؤلفه‌های صادرشده Android استفاده شود. برنامه مخرب می‌تواند از برنامه‌هایی که اجازه را اشتباه نوشته‌اند با یکی از روش‌های زیر سوءاستفاده کند:

  • درحال ثبت آن اجازه ابتدا
  • پیش‌بینی املا در برنامه‌های بعدی

این امر می‌تواند به برنامه کاربردی اجازه دهد دسترسی غیرمجاز به منابع داشته باشد یا برنامه کاربردی قربانی را کنترل کند.

برای مثال، برنامه آسیب‌پذیری می‌خواهد بااستفاده از اجازه READ_CONTACTS از مؤلفه‌ای محافظت کند اما به‌طور تصادفی اجازه را به‌صورت READ_CONACTS اشتباه می‌نویسد. برنامه مخرب می‌تواند READ_CONACTS را ادعا کند زیرا هیچ برنامه‌ای (یا سیستم) مالک آن نیست و به مؤلفه محافظت‌شده دسترسی پیدا کند. نوع رایج دیگر این آسیب‌پذیری android:permission=True است. مقادیری مثل true و false، صرف‌نظر از حروف بزرگ و کوچک، ورودی‌های نامعتبری برای اعلامیه اجازه هستند و با آن‌ها مشابه دیگر غلط‌های املایی در اعلامیه اجازه سفارشی رفتار می‌شود. برای رفع این مشکل، مقدار مشخصه android:permission باید به رشته اجازه معتبری تغییر کند. برای مثال، اگر برنامه نیاز به دسترسی به مخاطبین کاربر داشته باشد، مقدار مشخصه android:permission باید android.permission.READ_CONTACTS باشد.

کاهش

بررسی‌های Android Lint

هنگام اعلام اجازه‌های سفارشی، از بررسی‌های Android lint برای کمک به پیدا کردن غلط‌های املایی و سایر خطاهای احتمالی در کدتان استفاده کنید.

قرارداد نام‌گذاری

از قرارداد نام‌گذاری ثابتی استفاده کنید تا غلط‌های املایی بیشتر به‌چشم بیایند. بیانیه‌های اجازه سفارشی را در «مانیفست» برنامه‌تان به‌دقت بررسی کنید تا غلط املایی نداشته باشد.


ریسک: اجازه‌های یتیم

از اجازه‌ها برای محافظت از منابع برنامه‌ها استفاده می‌شود. دو مکان مختلف وجود دارد که برنامه می‌تواند اجازه‌های لازم برای دسترسی به منابع را در آن‌ها اعلام کند:

  • AndroidManifest.xml: ازپیش تعریف‌شده در فایل AndroidManifest.xml (اگر مشخص نشده باشد، از اجازه‌های <application> استفاده می‌شود)، برای مثال، اجازه ارائه‌دهنده ، اجازه گیرنده ، اجازه فعالیت ، اجازه سرویس ؛
  • کد: در کد زمان اجرا ثبت شده است، برای مثال registerReceiver().

بااین‌حال، گاهی این اجازه‌ها با برچسب <permission> مربوطه در مانیفست APK در دستگاه تعریف نمی‌شوند. در این حالت، به آن‌ها اجازه‌های یتیم می‌گویند. این وضعیت ممکن است به دلایل مختلفی رخ دهد، ازجمله:

  • ممکن است بین به‌روزرسانی‌های مانیفست و کد با بررسی اجازه، ناهماهنگی وجود داشته باشد
  • ممکن است APK دارای اجازه‌ها در ساخت گنجانده نشده باشد، یا ممکن است نسخه اشتباهی گنجانده شده باشد
  • ممکن است نام اجازه در بررسی یا مانیفست اشتباه هجی شده باشد

برنامه مخرب می‌تواند اجازه یتیم را تعریف کند و آن را به‌دست آورد. اگر این اتفاق بیفتد، برنامه‌های دارای امتیازی که برای محافظت از مؤلفه به اجازه یتیم اعتماد می‌کنند ممکن است به‌خطر بیفتند.

در مواردی که برنامه ممتاز از این اجازه برای محافظت یا محدود کردن هر مؤلفه‌ای استفاده می‌کند، این امر می‌تواند به برنامه مخرب اجازه دسترسی به آن مؤلفه را بدهد. برای مثال، راه‌اندازی فعالیت‌های محافظت‌شده با مجوز، دسترسی به ارائه‌دهنده محتوا، یا پخش کردن برای گیرنده رویداد ثبت‌شده محافظت‌شده با مجوز یتیم.

همچنین می‌تواند شرایطی ایجاد کند که برنامه دارای امتیاز فریب بخورد و برنامه مخرب را به‌عنوان برنامه قانونی بپذیرد و درنتیجه فایل‌ها یا محتوا را بار کند.

کاهش

مطمئن شوید همه اجازه‌های سفارشی که برنامه‌تان برای محافظت از مؤلفه‌ها استفاده می‌کند در «مانیفست» شما نیز تعریف شده باشد.

این برنامه از اجازه‌های سفارشی my.app.provider.READ و my.app.provider.WRITE برای محافظت از دسترسی به ارائه‌دهنده محتوا استفاده می‌کند:

Xml

<provider android:name="my.app.database.CommonContentProvider" android:readPermission="my.app.provider.READ" android:writePermission="my.app.provider.WRITE" android:exported="true" android:process=":myappservice" android:authorities="my.app.database.contentprovider"/>

این برنامه همچنین این اجازه‌های سفارشی را تعریف می‌کند و از آن‌ها استفاده می‌کند، بنابراین از انجام این کار توسط سایر برنامه‌های مخرب جلوگیری می‌کند:

Xml

<permission android:name="my.app.provider.READ"/>
<permission android:name="my.app.provider.WRITE"/>
<uses-permission android:name="my.app.provider.READ" />
<uses-permission android:name="my.app.provider.WRITE" />

خطر: android:protectionLevel سوءاستفاده‌شده

این مشخصه سطح خطر احتمالی را در اجازه شرح می‌دهد و نشان می‌دهد سیستم هنگام تصمیم‌گیری درباره اعطا کردن یا نکردن اجازه باید چه رویه‌هایی را دنبال کند.

کاهش

از سطح محافظت «معمولی» یا «خطرناک» اجتناب کنید

استفاده از protectionLevel معمولی یا خطرناک در اجازه‌هایتان یعنی اکثر برنامه‌ها می‌توانند این اجازه را درخواست کنند و بگیرند:

  • «normal» فقط نیاز به اعلام آن دارد
  • «خطرناک» توسط بسیاری از کاربران تأیید خواهد شد

بنابراین، این protectionLevels امنیت کمی را فراهم می‌کند.

استفاده از اجازه‌های امضا (Android نسخه ۱۰ و بالاتر)

هرجا ممکن است از سطوح محافظت امضا استفاده کنید. استفاده از این قابلیت تضمین می‌کند که فقط برنامه‌های دیگری که با همان گواهی برنامه ایجادکننده اجازه امضا شده‌اند می‌توانند به آن ویژگی‌های محافظت‌شده دسترسی داشته باشند. مطمئن شوید که از گواهی امضای اختصاصی (نه استفاده‌شده) استفاده می‌کنید و آن را به‌طور ایمن در مخزن کلید ذخیره کنید.

اجازه سفارشی را به‌صورت زیر در «مانیفست» خود تعریف کنید:

Xml

<permission
    android:name="my.custom.permission.MY_PERMISSION"
    android:protectionLevel="signature"/>

دسترسی به، مثلاً، یک فعالیت را فقط به برنامه‌هایی محدود کنید که این اجازه سفارشی به آن‌ها اعطا شده است، به این صورت:

Xml

<activity android:name=".MyActivity" android:permission="my.custom.permission.MY_PERMISSION"/>

هر برنامه دیگری که با همان گواهی برنامه اعلام‌کننده این اجازه سفارشی امضا شده باشد، دسترسی به فعالیت .MyActivity را دریافت خواهد کرد و باید آن را به‌صورت زیر در مانیفست خود اعلام کند:

Xml

<uses-permission android:name="my.custom.permission.MY_PERMISSION" />

مراقب «اجازه‌های سفارشی امضا» باشید (Android < 10)

اگر برنامه شما Android < 10 را هدف قرار می‌دهد، هرگاه اجازه‌های سفارشی برنامه شما به‌دلیل حذف نصب یا به‌روزرسانی برداشته شود، ممکن است برنامه‌های مخربی وجود داشته باشند که همچنان بتوانند از آن اجازه‌های سفارشی استفاده کنند و درنتیجه بررسی‌ها را دور بزنند. این به‌دلیل آسیب‌پذیری ارتقای امتیاز (CVE-2019-2200) است که در Android 10 برطرف شده است.

این یکی از دلایلی است (همراه با خطر شرایط رقابتی) که چرا بررسی‌های امضا نسبت‌به اجازه‌های سفارشی توصیه می‌شود.


خطر: شرایط رقابتی

اگر برنامه قانونی A اجازه سفارشی امضایی را تعریف کند که توسط برنامه‌های X دیگر استفاده می‌شود اما متعاقباً حذف نصب شود، برنامه مخرب B می‌تواند همان اجازه سفارشی را با protectionLevel دیگری تعریف کند، مثلاً عادی. به این ترتیب، B به همه مؤلفه‌های محافظت‌شده توسط آن اجازه سفارشی در برنامه‌های X دسترسی پیدا می‌کند، بدون اینکه نیازی به امضا شدن با همان گواهی برنامه A باشد.

اگر B قبل‌از A نصب شود، همین اتفاق می‌افتد.

کاهش

اگر می‌خواهید مؤلفه‌ای را فقط برای برنامه‌هایی دردسترس قرار دهید که با همان امضای برنامه ارائه‌دهنده امضا شده‌اند، ممکن است بتوانید از تعریف اجازه‌های سفارشی برای محدود کردن دسترسی به آن مؤلفه اجتناب کنید. در این شرایط می‌توانید از بررسی‌های امضا استفاده کنید. وقتی یکی از برنامه‌هایتان درخواستی برای یکی دیگر از برنامه‌هایتان ارسال می‌کند، برنامه دوم می‌تواند قبل‌از پذیرفتن درخواست، درستی‌سنجی کند که هر دو برنامه با گواهی یکسانی امضا شده باشند.


منابع