رده OWASP: MASVS-CODE: کیفیت کد
نمای کلی
خطرات مرتبط با مجوزهای سفارشی زمانی ایجاد میشوند که یا تعریف مجوزهای سفارشی وجود نداشته باشد یا غلط املایی داشته باشد، یا زمانی که ویژگی android:protectionLevel مربوطه در Manifest مورد سوءاستفاده قرار گیرد.
برای مثال، این خطرات میتوانند با ایجاد یک مجوز سفارشی با نام یکسان، اما تعریفشده توسط یک برنامه مخرب و با سطوح حفاظتی متفاوت اعمالشده، مورد سوءاستفاده قرار گیرند.
مجوزهای سفارشی برای فعال کردن اشتراکگذاری منابع و قابلیتها با سایر برنامهها طراحی شدهاند. نمونههایی از استفاده مشروع از مجوزهای سفارشی میتواند موارد زیر باشد:
- کنترل ارتباطات بین فرآیندی (IPC) بین دو یا چند برنامه
- دسترسی به سرویسهای شخص ثالث
- محدود کردن دسترسی به دادههای اشتراکی یک برنامه
تأثیر
تأثیر سوءاستفاده از این آسیبپذیری این است که یک برنامه مخرب میتواند به منابعی که در ابتدا قرار بود محافظت شوند، دسترسی پیدا کند. پیامدهای این آسیبپذیری به منبعی که محافظت میشود و مجوزهای مرتبط با سرویس برنامه اصلی بستگی دارد.
ریسک: اشتباهات تایپی در مجوزهای سفارشی
ممکن است یک مجوز سفارشی در مانیفست اعلام شده باشد، اما به دلیل یک غلط املایی، از یک مجوز سفارشی متفاوت برای محافظت از اجزای اندروید صادر شده استفاده شود. یک برنامه مخرب میتواند از برنامههایی که مجوز را به یکی از دلایل زیر اشتباه تایپ کردهاند، سوءاستفاده کند:
- ابتدا آن مجوز را ثبت کنید
- پیشبینی املا در درخواستهای بعدی
این میتواند به یک برنامه اجازه دسترسی غیرمجاز به منابع یا کنترل برنامه قربانی را بدهد.
برای مثال، یک برنامهی آسیبپذیر میخواهد با استفاده از مجوز READ_CONTACTS از یک کامپوننت محافظت کند، اما بهطور تصادفی مجوز را به اشتباه READ_CONACTS مینویسد. یک برنامهی مخرب میتواند READ_CONACTS درخواست کند، زیرا متعلق به هیچ برنامه (یا سیستمی) نیست و به کامپوننت محافظتشده دسترسی پیدا کند. یکی دیگر از انواع رایج این آسیبپذیری android:permission=True است. مقادیری مانند true و false ، صرف نظر از حروف بزرگ و کوچک بودن، ورودیهای نامعتبر برای اعلان مجوز هستند و مانند سایر اشتباهات تایپی اعلان مجوز سفارشی با آنها رفتار میشود. برای رفع این مشکل، مقدار ویژگی android:permission باید به یک رشتهی مجوز معتبر تغییر یابد. برای مثال، اگر برنامه نیاز به دسترسی به مخاطبین کاربر دارد، مقدار ویژگی android:permission باید android.permission.READ_CONTACTS باشد.
کاهشها
بررسیهای Lint اندروید
هنگام تعریف مجوزهای سفارشی، از بررسیهای lint اندروید برای یافتن غلطهای املایی و سایر خطاهای احتمالی در کد خود استفاده کنید.
کنوانسیون نامگذاری
از یک قرارداد نامگذاری ثابت استفاده کنید تا اشتباهات تایپی قابل توجهتر شوند. اعلانهای مجوز سفارشی در مانیفست برنامه خود را با دقت بررسی کنید تا اشتباهات تایپی را پیدا کنید.
ریسک: مجوزهای یتیم
مجوزها برای محافظت از منابع برنامهها استفاده میشوند. دو مکان مختلف وجود دارد که یک برنامه میتواند مجوزهای مورد نیاز برای دسترسی به منابع را اعلام کند:
- AndroidManifest.xml: از پیش تعریف شده در فایل AndroidManifest.xml (در صورت مشخص نشدن، از مجوزهای
<application>استفاده میشود)، مانند: مجوز ارائه دهنده ، مجوز گیرنده ، مجوز فعالیت ، مجوز سرویس ؛ - کد: در کد زمان اجرا ثبت شده است، مثلاً
registerReceiver().
با این حال، گاهی اوقات این مجوزها توسط یک برچسب <permission> مربوطه در Manifest یک APK روی دستگاه تعریف نمیشوند. در این حالت، به آنها مجوزهای یتیم گفته میشود. این وضعیت میتواند به دلایل مختلفی رخ دهد، مانند:
- ممکن است بین بهروزرسانیهای مانیفست و کدی که بررسی مجوز را انجام میدهد، ناهمگامی وجود داشته باشد.
- ممکن است فایل APK دارای مجوزها در نسخه نهایی گنجانده نشده باشد، یا نسخه اشتباهی در آن گنجانده شده باشد.
- ممکن است نام مجوز در چک یا مانیفست اشتباه نوشته شده باشد.
یک برنامه مخرب میتواند یک مجوز یتیم تعریف کند و آن را به دست آورد. اگر این اتفاق بیفتد، برنامههای دارای امتیاز که به مجوز یتیم برای محافظت از یک جزء اعتماد دارند، میتوانند به خطر بیفتند.
در مواردی که برنامهی دارای امتیاز از مجوز برای محافظت یا محدود کردن هر مؤلفهای استفاده میکند، این میتواند به برنامهی مخرب دسترسی به آن مؤلفه را اعطا کند. مثالهایی از این موارد شامل راهاندازی فعالیتهای محافظتشده توسط یک مجوز، دسترسی به یک ارائهدهندهی محتوا یا پخش به یک گیرندهی پخش محافظتشده توسط مجوز یتیمشده است.
همچنین میتواند وضعیتی ایجاد کند که در آن برنامهی دارای امتیاز بالا فریب بخورد و باور کند که برنامهی مخرب یک برنامهی قانونی است و بنابراین فایلها یا محتوا را بارگیری کند.
کاهشها
مطمئن شوید که تمام مجوزهای سفارشی که برنامه شما برای محافظت از کامپوننتها استفاده میکند، در Manifest شما نیز تعریف شدهاند.
این برنامه از مجوزهای سفارشی my.app.provider.READ و my.app.provider.WRITE برای محافظت از دسترسی به یک ارائهدهنده محتوا استفاده میکند:
ایکس ام ال
<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"/>
این برنامه همچنین این مجوزهای سفارشی را تعریف و استفاده میکند، بنابراین از انجام این کار توسط سایر برنامههای مخرب جلوگیری میکند:
ایکس ام ال
<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 نرمال یا خطرناک برای مجوزهای شما به این معنی است که اکثر برنامهها میتوانند درخواست مجوز کنند و آن را دریافت کنند:
- «عادی» فقط نیاز به اعلام آن دارد
- «خطرناک» توسط بسیاری از کاربران تأیید خواهد شد.
بنابراین، این protectionLevels امنیت کمی را فراهم میکنند.
استفاده از مجوزهای امضا (اندروید >= 10)
هر جا که ممکن است از سطوح حفاظت امضا استفاده کنید. استفاده از این قابلیت تضمین میکند که فقط برنامههای دیگری که با همان گواهی برنامهای که مجوز را ایجاد کرده امضا شدهاند، میتوانند به آن ویژگیهای محافظتشده دسترسی داشته باشند. مطمئن شوید که از یک گواهی امضای اختصاصی (که دوباره استفاده نشده) استفاده میکنید و آن را به طور ایمن در یک keystore ذخیره کنید.
یک مجوز سفارشی به صورت زیر در Manifest خود تعریف کنید:
ایکس ام ال
<permission
android:name="my.custom.permission.MY_PERMISSION"
android:protectionLevel="signature"/>
دسترسی به مثلاً یک فعالیت را فقط به برنامههایی که این مجوز سفارشی را دارند، محدود کنید، به شرح زیر:
ایکس ام ال
<activity android:name=".MyActivity" android:permission="my.custom.permission.MY_PERMISSION"/>
هر برنامه دیگری که با همان گواهی برنامهای که این مجوز سفارشی را اعلام کرده است، امضا شده باشد، به اکتیویتی .MyActivity دسترسی خواهد داشت و باید آن را به صورت زیر در مانیفست خود اعلام کند:
ایکس ام ال
<uses-permission android:name="my.custom.permission.MY_PERMISSION" />
مراقب مجوزهای سفارشی امضا باشید (اندروید <10)
اگر برنامه شما اندروید پایینتر از ۱۰ را هدف قرار میدهد، هر زمان که مجوزهای سفارشی برنامه شما به دلیل حذف یا بهروزرسانی حذف شوند، ممکن است برنامههای مخرب همچنان بتوانند از آن مجوزهای سفارشی استفاده کنند و در نتیجه بررسیها را دور بزنند. این به دلیل آسیبپذیری افزایش امتیاز ( CVE-2019-2200 ) است که در اندروید ۱۰ برطرف شده است.
این یکی از دلایلی است (همراه با خطر شرایط رقابتی) که بررسی امضا را به مجوزهای سفارشی ترجیح میدهند.
خطر: شرایط نژادی
اگر یک برنامهی قانونی A یک مجوز سفارشی امضا تعریف کند که توسط سایر برنامههای X استفاده میشود اما متعاقباً حذف نصب شود، یک برنامهی مخرب B میتواند همان مجوز سفارشی را با یک protectionLevel متفاوت، مثلاً normal ، تعریف کند. به این ترتیب، B به تمام اجزای محافظتشده توسط آن مجوز سفارشی در برنامههای X دسترسی پیدا میکند، بدون اینکه نیازی به امضا شدن با همان گواهینامهی برنامهی A داشته باشد.
اگر B قبل از A نصب شود، همین اتفاق میافتد.
کاهشها
اگر میخواهید یک جزء را فقط برای برنامههایی که با امضای مشابه برنامهی ارائهدهنده امضا شدهاند، در دسترس قرار دهید، ممکن است بتوانید از تعریف مجوزهای سفارشی برای محدود کردن دسترسی به آن جزء اجتناب کنید. در این شرایط میتوانید از بررسی امضا استفاده کنید. وقتی یکی از برنامههای شما درخواستی برای یکی دیگر از برنامههای شما ارسال میکند، برنامهی دوم میتواند قبل از اجابت درخواست، تأیید کند که هر دو برنامه با گواهی یکسان امضا شدهاند.
منابع
- درخواستهای مجوز خود را به حداقل برسانید
- مرور کلی مجوزها
- شرح سطوح حفاظت
- CustomPermissionTypo اندروید Lint
- نحوه استفاده از Lint اندروید
- مقاله تحقیقاتی با توضیح عمیق مجوزهای اندروید و یافتههای جالب تست فاز