اندروید دارای ویژگی های امنیتی داخلی است که به طور قابل توجهی فرکانس و تأثیر مسائل امنیتی برنامه را کاهش می دهد. این سیستم به گونه ای طراحی شده است که شما معمولاً می توانید برنامه های خود را با مجوزهای سیستم و فایل پیش فرض بسازید و از تصمیم گیری های دشوار در مورد امنیت اجتناب کنید.
ویژگی های امنیتی اصلی زیر به شما کمک می کند تا برنامه های امن بسازید:
- سندباکس برنامه اندروید، که داده های برنامه و اجرای کد شما را از سایر برنامه ها جدا می کند.
- یک چارچوب کاربردی با پیاده سازی قوی از عملکردهای امنیتی رایج مانند رمزنگاری، مجوزها و ارتباطات بین فرآیندی ایمن (IPC).
- فناوریهایی مانند تصادفیسازی طرحبندی فضای آدرس (ASLR) ، بدون اجرا (NX) ، ProPolice، safe_iop ، OpenBSD
dlmalloc
وcalloc
، و لینوکسmmap_min_addr
برای کاهش خطرات مرتبط با خطاهای رایج مدیریت حافظه. - مجوزهای اعطا شده توسط کاربر برای محدود کردن دسترسی به ویژگی های سیستم و داده های کاربر.
- مجوزهای تعریف شده توسط برنامه برای کنترل داده های برنامه بر اساس هر برنامه.
آشنایی با بهترین روش های امنیتی اندروید در این صفحه بسیار مهم است. پیروی از این شیوهها بهعنوان عادتهای عمومی کدنویسی به شما کمک میکند تا از معرفی سهواً مسائل امنیتی که بر کاربران شما تأثیر منفی میگذارد، جلوگیری کنید.
احراز هویت
احراز هویت یک پیش نیاز برای بسیاری از عملیات امنیتی کلیدی است. برای کنترل دسترسی به دارایی های محافظت شده مانند داده های کاربر، عملکرد برنامه و سایر منابع، باید احراز هویت را به برنامه Android خود اضافه کنید.
میتوانید تجربه احراز هویت کاربر خود را با ادغام برنامه خود با Credential Manager بهبود بخشید. Credential Manager یک کتابخانه Android Jetpack است که پشتیبانی API را برای اکثر روشهای اصلی احراز هویت، از جمله کلیدهای عبور، گذرواژهها و راهحلهای ورود به سیستم فدرال مانند Sign-in with Google یکپارچه میکند.
برای افزایش بیشتر امنیت برنامه خود، روشهای احراز هویت بیومتریک مانند اسکن اثر انگشت یا تشخیص چهره را اضافه کنید. نامزدهای خوب برای افزودن احراز هویت بیومتریک ممکن است شامل برنامه هایی برای مدیریت مالی، مراقبت های بهداشتی یا هویت باشد.
فریم ورک تکمیل خودکار اندروید میتواند فرآیند ثبتنام و ورود را آسانتر کند و نرخ خطا و اصطکاک کاربر را کاهش دهد. تکمیل خودکار با مدیران رمز عبور ادغام می شود و به کاربران امکان می دهد رمزهای عبور پیچیده و تصادفی را انتخاب کنند که می توانند به راحتی و ایمن ذخیره و بازیابی شوند.
یکپارچگی برنامه
Play Integrity API به شما کمک میکند بررسی کنید که تعاملات و درخواستهای سرور از باینری برنامه واقعی شما که روی یک دستگاه مجهز به Android واقعی اجرا میشود، میآیند. با شناسایی تعاملات بالقوه مخاطره آمیز و تقلبی، مانند نسخه های برنامه دستکاری شده و محیط های غیرقابل اعتماد، سرور پشتیبان برنامه شما می تواند با اقدامات مناسب برای جلوگیری از حملات و کاهش سوء استفاده پاسخ دهد.
ذخیره سازی داده ها
رایج ترین نگرانی امنیتی برای یک برنامه در Android این است که آیا داده هایی که در دستگاه ذخیره می کنید برای سایر برنامه ها قابل دسترسی است یا خیر. سه راه اساسی برای ذخیره داده ها در دستگاه وجود دارد:
- حافظه داخلی
- ذخیره سازی خارجی
- ارائه دهندگان محتوا
بخشهای زیر مسائل امنیتی مرتبط با هر رویکرد را شرح میدهند.
حافظه داخلی
به طور پیشفرض، فایلهایی که در حافظه داخلی ایجاد میکنید فقط برای برنامه شما قابل دسترسی هستند. اندروید این حفاظت را اجرا می کند و برای اکثر برنامه ها کافی است.
از حالتهای منسوخ MODE_WORLD_WRITEABLE
و MODE_WORLD_READABLE
برای فایلهای IPC اجتناب کنید. آنها توانایی محدود کردن دسترسی به داده ها به برنامه های خاص را ارائه نمی دهند، و هیچ گونه کنترلی بر قالب داده ارائه نمی دهند. اگر میخواهید دادههای خود را با سایر فرآیندهای برنامه به اشتراک بگذارید، به جای آن از یک ارائهدهنده محتوا استفاده کنید، که مجوز خواندن و نوشتن را به برنامههای دیگر ارائه میدهد و میتواند مجوزهای پویا را به صورت موردی اعطا کند.
ذخیره سازی خارجی
فایلهای ایجاد شده در حافظه خارجی ، مانند کارتهای SD، در سطح جهانی قابل خواندن و نوشتن هستند. از آنجا که حافظه خارجی می تواند توسط کاربر حذف شود و همچنین توسط هر برنامه ای اصلاح شود، فقط اطلاعات غیر حساس را با استفاده از حافظه خارجی ذخیره کنید.
هنگام مدیریت دادهها از حافظه خارجی مانند دادههای هر منبع غیرقابل اعتماد ، اعتبار ورودی را انجام دهید . فایل های اجرایی یا کلاس را قبل از بارگذاری پویا در حافظه خارجی ذخیره نکنید. اگر برنامه شما فایلهای اجرایی را از حافظه خارجی بازیابی میکند، مطمئن شوید که فایلها قبل از بارگیری پویا امضا شده و از نظر رمزنگاری تأیید شدهاند.
ارائه دهندگان محتوا
ارائه دهندگان محتوا مکانیزم ذخیره سازی ساختار یافته ای را ارائه می دهند که می تواند به برنامه شخصی شما محدود شود یا برای دسترسی به سایر برنامه ها صادر شود. اگر قصد ندارید به برنامه های دیگر دسترسی به ContentProvider
خود ارائه دهید، آن را به عنوان android:exported=false
در مانیفست برنامه علامت بزنید. در غیر این صورت، ویژگی android:exported
روی true
تنظیم کنید تا به سایر برنامه ها اجازه دسترسی به داده های ذخیره شده را بدهید.
هنگام ایجاد یک ContentProvider
که برای استفاده توسط سایر برنامه ها صادر می شود، می توانید یک مجوز برای خواندن و نوشتن مشخص کنید، یا می توانید مجوزهای مجزایی برای خواندن و نوشتن مشخص کنید. مجوزهای خود را به موارد مورد نیاز برای انجام وظیفه محدود کنید. به خاطر داشته باشید که معمولاً اضافه کردن مجوزها بعداً برای نمایش عملکردهای جدید آسان تر از حذف آنها و تأثیرگذاری بر کاربران فعلی است.
اگر از یک ارائهدهنده محتوا برای اشتراکگذاری دادهها فقط بین برنامههای خود استفاده میکنید، توصیه میکنیم از ویژگی android:protectionLevel
برای محافظت signature
استفاده کنید. مجوزهای امضا نیازی به تأیید کاربر ندارند، بنابراین وقتی برنامههایی که به دادهها دسترسی دارند با یک کلید امضا میشوند، تجربه کاربری بهتر و دسترسی کنترلشدهتری به دادههای ارائهدهنده محتوا ارائه میکنند.
ارائهدهندگان محتوا همچنین میتوانند با اعلام ویژگی android:grantUriPermissions
و استفاده از پرچمهای FLAG_GRANT_READ_URI_PERMISSION
و FLAG_GRANT_WRITE_URI_PERMISSION
در شی Intent
که مؤلفه را فعال میکند، دسترسی دقیقتری را فراهم کنند. دامنه این مجوزها را می توان با عنصر <grant-uri-permission>
محدودتر کرد.
هنگام دسترسی به ارائهدهنده محتوا، از روشهای پرس و جوی پارامتری مانند query
، update
و delete()
استفاده کنید تا از تزریق احتمالی SQL از منابع نامعتبر جلوگیری کنید. توجه داشته باشید که اگر آرگومان selection
با الحاق دادههای کاربر قبل از ارسال به متد ساخته شود، استفاده از روشهای پارامتری کافی نیست.
در مورد مجوز نوشتن احساس امنیت کاذب نداشته باشید. مجوز نوشتن به عبارات SQL اجازه می دهد تا برخی از داده ها را با استفاده از بندهای WHERE
خلاقانه و تجزیه نتایج تأیید کنند. به عنوان مثال، یک مهاجم ممکن است وجود یک شماره تلفن خاص در گزارش تماس را با اصلاح یک ردیف تنها در صورتی که آن شماره تلفن از قبل وجود داشته باشد، بررسی کند. اگر دادههای ارائهدهنده محتوا ساختار قابل پیشبینی داشته باشند، مجوز نوشتن ممکن است معادل ارائه خواندن و نوشتن باشد.
مجوزها
از آنجایی که اندروید برنامهها را از یکدیگر جدا میکند، برنامهها باید بهصراحت منابع و دادهها را به اشتراک بگذارند. آنها این کار را با اعلام مجوزهای مورد نیاز خود برای قابلیتهای اضافی که توسط سندباکس اولیه ارائه نشده است، از جمله دسترسی به ویژگیهای دستگاه مانند دوربین، انجام میدهند.
درخواست های مجوز
تعداد مجوزهایی را که برنامه شما درخواست می کند به حداقل برسانید. محدود کردن دسترسی به مجوزهای حساس خطر سوء استفاده ناخواسته از آن مجوزها را کاهش می دهد، پذیرش کاربر را بهبود می بخشد و برنامه شما را برای مهاجمان آسیب پذیرتر می کند. به طور کلی، اگر مجوزی برای عملکرد برنامه شما لازم نیست، آن را درخواست نکنید. راهنمای ارزیابی اینکه آیا برنامه شما نیاز به اعلام مجوز دارد یا خیر را ببینید.
در صورت امکان، برنامه خود را به گونه ای طراحی کنید که به هیچ مجوزی نیاز نداشته باشد. به عنوان مثال، به جای درخواست دسترسی به اطلاعات دستگاه برای ایجاد یک شناسه منحصر به فرد، یک UUID برای برنامه خود ایجاد کنید. (در بخش اطلاعات کاربر بیشتر بیاموزید). یا به جای استفاده از حافظه خارجی (که نیاز به مجوز دارد)، داده ها را در حافظه داخلی ذخیره کنید.
علاوه بر درخواست مجوز، برنامه شما میتواند از عنصر <permission>
برای محافظت از IPC که به امنیت حساس است و در معرض سایر برنامهها، مانند ContentProvider
است، استفاده کند. به طور کلی، توصیه می کنیم در صورت امکان از کنترل های دسترسی به غیر از مجوزهای تأیید شده توسط کاربر استفاده کنید، زیرا مجوزها ممکن است برای کاربران گیج کننده باشند. به عنوان مثال، استفاده از سطح حفاظت از امضا را در مجوزهای ارتباط IPC بین برنامه های کاربردی ارائه شده توسط یک توسعه دهنده در نظر بگیرید.
داده های محافظت شده با مجوز را افشا نکنید. این زمانی اتفاق میافتد که برنامه شما دادههایی را از طریق IPC نشان میدهد که فقط به این دلیل در دسترس هستند که برنامه شما اجازه دسترسی به آن دادهها را دارد. ممکن است مشتریان رابط IPC برنامه شما همان مجوز دسترسی به داده را نداشته باشند. جزئیات بیشتر در مورد فراوانی و اثرات بالقوه این موضوع در مقاله تحقیقاتی Permission Re-Delegation: Attacks and Defenses منتشر شده در USENIX آمده است.
تعاریف مجوز
کوچکترین مجموعه ای از مجوزها را که الزامات امنیتی شما را برآورده می کند، تعریف کنید. ایجاد یک مجوز جدید برای اکثر برنامه ها نسبتاً غیر معمول است، زیرا مجوزهای تعریف شده توسط سیستم موقعیت های زیادی را پوشش می دهند. در صورت لزوم، بررسی های دسترسی را با استفاده از مجوزهای موجود انجام دهید.
اگر به مجوز جدیدی نیاز دارید، در نظر بگیرید که آیا میتوانید کار خود را با سطح حفاظت از امضا انجام دهید. مجوزهای امضا برای کاربر شفاف است و فقط به برنامههایی که توسط همان توسعهدهنده امضا شدهاند اجازه دسترسی را میدهد که برنامهای که بررسی مجوز را انجام میدهد.
اگر ایجاد مجوز جدید همچنان مورد نیاز است، آن را با استفاده از عنصر <permission>
در مانیفست برنامه اعلام کنید. برنامه هایی که از مجوز جدید استفاده می کنند می توانند با افزودن عنصر <uses-permission>
در فایل های مانیفست خود به آن ارجاع دهند. همچنین می توانید با استفاده از متد addPermission()
مجوزها را به صورت پویا اضافه کنید.
اگر مجوزی با سطح حفاظت خطرناک ایجاد کنید، تعدادی پیچیدگی وجود دارد که باید در نظر بگیرید:
- مجوز باید دارای رشته ای باشد که به طور خلاصه تصمیم امنیتی مورد نیاز کاربر را بیان کند.
- رشته مجوز باید به زبان های مختلف محلی باشد.
- کاربران ممکن است تصمیم بگیرند که یک برنامه را نصب نکنند زیرا یک مجوز گیج کننده است یا به عنوان خطرناک تلقی می شود.
- زمانی که سازنده مجوز نصب نشده باشد، برنامهها ممکن است درخواست مجوز کنند.
هر یک از اینها چالش غیرفنی مهمی را برای شما به عنوان توسعهدهنده ایجاد میکند و در عین حال کاربران شما را گیج میکند، به همین دلیل است که ما از استفاده از سطح مجوز خطرناک جلوگیری میکنیم.
شبکه سازی
تراکنشهای شبکه ذاتاً برای امنیت خطرناک هستند، زیرا شامل انتقال دادههایی هستند که به طور بالقوه خصوصی برای کاربر هستند. مردم به طور فزاینده ای از نگرانی های مربوط به حریم خصوصی یک دستگاه تلفن همراه آگاه هستند، به خصوص زمانی که دستگاه تراکنش های شبکه را انجام می دهد، بنابراین بسیار مهم است که برنامه شما بهترین شیوه ها را برای ایمن نگه داشتن داده های کاربر در همه زمان ها اجرا کند.
شبکه IP
شبکه سازی در اندروید تفاوت قابل توجهی با سایر محیط های لینوکس ندارد. نکته کلیدی این است که مطمئن شوید که از پروتکل های مناسب برای داده های حساس استفاده می شود، مانند HttpsURLConnection
برای ترافیک امن وب. از HTTPS روی HTTP در هر جایی که HTTPS روی سرور پشتیبانی میشود، استفاده کنید، زیرا دستگاههای تلفن همراه اغلب به شبکههایی متصل میشوند که ایمن نیستند، مانند نقاط اتصال Wi-Fi عمومی.
ارتباطات سطح سوکت احراز هویت شده و رمزگذاری شده را می توان به راحتی با استفاده از کلاس SSLSocket
پیاده سازی کرد. با توجه به فرکانس اتصال دستگاههای اندرویدی به شبکههای بیسیم ناامن با استفاده از Wi-Fi، استفاده از شبکه امن برای همه برنامههایی که از طریق شبکه ارتباط برقرار میکنند به شدت توصیه میشود.
برخی از برنامه ها از پورت های شبکه میزبان محلی برای مدیریت IPC حساس استفاده می کنند. از این روش استفاده نکنید، زیرا این رابط ها توسط سایر برنامه های موجود در دستگاه قابل دسترسی هستند. در عوض، از مکانیزم Android IPC در جایی که امکان احراز هویت وجود دارد، مانند یک Service
استفاده کنید. اتصال به آدرس IP غیر اختصاصی INADDR_ANY
بدتر از استفاده از حلقه بک است، زیرا به برنامه شما اجازه می دهد درخواست ها را از هر آدرس IP دریافت کند.
مطمئن شوید که به داده های دانلود شده از HTTP یا سایر پروتکل های ناامن اعتماد ندارید. این شامل اعتبار سنجی ورودی در WebView
و هرگونه پاسخی به اهداف صادر شده علیه HTTP است.
شبکه تلفن
پروتکل سرویس پیام کوتاه (SMS) در درجه اول برای ارتباط کاربر به کاربر طراحی شده است و برای برنامه هایی که می خواهند داده ها را انتقال دهند مناسب نیست. با توجه به محدودیتهای پیامک، توصیه میکنیم از Firebase Cloud Messaging (FCM) و شبکه IP برای ارسال پیامهای داده از یک وب سرور به برنامه خود در دستگاه کاربر استفاده کنید.
توجه داشته باشید که پیامک نه رمزگذاری شده است و نه در شبکه یا دستگاه به شدت احراز هویت می شود. به ویژه، هر گیرنده پیامک باید انتظار داشته باشد که یک کاربر مخرب ممکن است پیامک را به برنامه شما ارسال کرده باشد. برای اجرای دستورات حساس به داده های پیامک تایید نشده تکیه نکنید. همچنین، توجه داشته باشید که پیامک ممکن است در معرض جعل و/یا رهگیری در شبکه باشد. در خود دستگاه مجهز به اندروید، پیامهای SMS بهعنوان مقاصد پخش ارسال میشوند، بنابراین میتوانند توسط برنامههای کاربردی دیگری که مجوز READ_SMS
را دارند، خوانده یا ضبط کنند.
اعتبار سنجی ورودی
اعتبار سنجی ناکافی ورودی یکی از رایج ترین مشکلات امنیتی است که برنامه ها را تحت تأثیر قرار می دهد، صرف نظر از اینکه روی چه پلتفرمی اجرا می شوند. Android اقدامات متقابلی در سطح پلت فرم دارد که قرار گرفتن برنامهها در معرض مشکلات اعتبارسنجی ورودی را کاهش میدهد، و توصیه میکنیم در صورت امکان از این ویژگیها استفاده کنید. همچنین، توصیه میکنیم از زبانهای ایمن برای کاهش احتمال مشکلات اعتبارسنجی ورودی استفاده کنید.
اگر از کد بومی استفاده میکنید، هر دادهای که از فایلها خوانده میشود، از طریق شبکه دریافت میشود یا از IPC دریافت میشود، پتانسیل ایجاد یک مشکل امنیتی را دارد. رایجترین مشکلات سرریز بافر ، استفاده پس از رایگان و خطاهای یک به یک است. اندروید تعدادی فناوری مانند ASLR و Data Execution Prevention (DEP) ارائه میکند که قابلیت بهرهبرداری از این خطاها را کاهش میدهند، اما مشکل اساسی را حل نمیکنند. شما می توانید با مدیریت دقیق اشاره گرها و مدیریت بافرها از این آسیب پذیری ها جلوگیری کنید.
زبانهای پویا و مبتنی بر رشته مانند جاوا اسکریپت و SQL نیز به دلیل کاراکترهای فرار و تزریق اسکریپت در معرض مشکلات اعتبارسنجی ورودی هستند.
اگر از دادههایی در جستارهایی استفاده میکنید که به پایگاه داده SQL یا ارائهدهنده محتوا ارسال میشوند، تزریق SQL میتواند مشکل ساز باشد. بهترین دفاع استفاده از پرس و جوهای پارامتری است، همانطور که در بخش ارائه دهندگان محتوا بحث شد. محدود کردن مجوزها به فقط خواندن یا نوشتن فقط میتواند احتمال آسیبهای مرتبط با تزریق SQL را کاهش دهد.
اگر نمیتوانید از ویژگیهای امنیتی مورد بحث در این بخش استفاده کنید، مطمئن شوید که از قالبهای داده با ساختار مناسب استفاده میکنید و بررسی کنید که دادهها با قالب مورد انتظار مطابقت دارند. در حالی که مسدود کردن کاراکترهای خاص یا انجام جایگزینی کاراکتر می تواند یک استراتژی موثر باشد، این تکنیک ها در عمل مستعد خطا هستند و توصیه می کنیم در صورت امکان از آنها اجتناب کنید.
داده های کاربر
بهترین رویکرد برای امنیت داده های کاربر، به حداقل رساندن استفاده از API هایی است که به اطلاعات حساس یا شخصی دسترسی دارند. اگر به داده های کاربر دسترسی دارید، در صورت امکان از ذخیره یا انتقال آنها خودداری کنید. در نظر بگیرید که آیا منطق برنامه شما را می توان با استفاده از یک فرم هش یا غیر قابل برگشت از داده ها پیاده سازی کرد. برای مثال، برنامه شما ممکن است از هش آدرس ایمیل به عنوان کلید اصلی برای جلوگیری از انتقال یا ذخیره آدرس ایمیل استفاده کند. این امر شانس افشای ناخواسته داده ها را کاهش می دهد و همچنین احتمال تلاش مهاجمان برای سوء استفاده از برنامه شما را کاهش می دهد.
هر زمان که نیاز به دسترسی به داده های خصوصی است، کاربر خود را احراز هویت کنید و از روش های احراز هویت مدرن مانند کلیدهای عبور و مدیریت اعتبار استفاده کنید. اگر برنامه شما نیاز به دسترسی به اطلاعات شخصی دارد، به خاطر داشته باشید که برخی از حوزه های قضایی ممکن است از شما بخواهند که یک خط مشی رازداری برای توضیح استفاده و ذخیره آن داده ها ارائه دهید. از بهترین روش امنیتی برای به حداقل رساندن دسترسی به داده های کاربر برای ساده سازی انطباق پیروی کنید.
همچنین، در نظر داشته باشید که آیا برنامه شما میتواند به طور ناخواسته اطلاعات شخصی را در اختیار اشخاص دیگر قرار دهد، مانند اجزای شخص ثالث برای تبلیغات یا خدمات شخص ثالثی که برنامه شما استفاده میکند. اگر نمی دانید چرا یک جزء یا سرویس به اطلاعات شخصی نیاز دارد، آن را ارائه ندهید. به طور کلی، کاهش دسترسی به اطلاعات شخصی توسط اپلیکیشن شما، احتمال بروز مشکلات در این زمینه را کاهش می دهد.
اگر برنامه شما نیاز به دسترسی به داده های حساس دارد، ارزیابی کنید که آیا باید آن را به سرور منتقل کنید یا می توانید این عملیات را روی کلاینت اجرا کنید. برای جلوگیری از انتقال داده های کاربر، هر کدی را با استفاده از داده های حساس روی کلاینت اجرا کنید. همچنین، مطمئن شوید که دادههای کاربر را ناخواسته از طریق IPC بیش از حد مجاز، فایلهای قابل نوشتن در جهان یا سوکتهای شبکه در معرض سایر برنامههای روی دستگاه قرار ندهید. IPC بیش از حد مجاز یک مورد خاص از نشت داده های محافظت شده با مجوز است که در بخش درخواست های مجوز مورد بحث قرار گرفته است.
اگر یک شناسه جهانی منحصر به فرد (GUID) مورد نیاز است، یک شماره بزرگ و منحصر به فرد ایجاد کنید و آن را ذخیره کنید. از شناسه های تلفن مانند شماره تلفن یا IMEI که ممکن است با اطلاعات شخصی مرتبط باشد استفاده نکنید. این موضوع با جزئیات بیشتری در صفحه مربوط به بهترین روش ها برای شناسه های منحصر به فرد مورد بحث قرار گرفته است.
هنگام نوشتن در گزارشهای روی دستگاه مراقب باشید. در Android، گزارشها یک منبع مشترک هستند و با مجوز READ_LOGS
برای یک برنامه کاربردی در دسترس هستند. حتی اگر دادههای گزارش تلفن موقتی است و در هنگام راهاندازی مجدد پاک میشود، ثبت نامناسب اطلاعات کاربر میتواند به طور ناخواسته دادههای کاربر را به برنامههای دیگر نشت کند. علاوه بر عدم ثبت PII، استفاده از گزارش را در برنامه های تولیدی محدود کنید. برای پیاده سازی آسان این، از پرچم های اشکال زدایی و کلاس های Log
سفارشی با سطوح ثبت به راحتی قابل تنظیم استفاده کنید.
WebView
از آنجایی که WebView
محتوای وب را مصرف میکند که میتواند شامل HTML و جاوا اسکریپت باشد، استفاده نادرست میتواند باعث ایجاد مشکلات رایج امنیتی وب مانند اسکریپت بین سایتی (تزریق جاوا اسکریپت) شود. Android شامل تعدادی مکانیسم برای کاهش دامنه این مشکلات بالقوه با محدود کردن قابلیت WebView
به حداقل عملکرد مورد نیاز برنامه شما است.
اگر برنامه شما مستقیماً از جاوا اسکریپت در WebView
استفاده نمی کند، setJavaScriptEnabled
صدا نکنید . برخی از کدهای نمونه از این روش استفاده می کنند. اگر کد نمونه ای را که از آن در یک برنامه تولیدی استفاده می کند، استفاده مجدد می کنید، اگر نیازی به آن نیست، آن فراخوانی متد را حذف کنید. به طور پیش فرض، WebView
جاوا اسکریپت را اجرا نمی کند، بنابراین اسکریپت بین سایتی امکان پذیر نیست.
از addJavaScriptInterface()
با دقت خاصی استفاده کنید، زیرا به جاوا اسکریپت اجازه میدهد تا عملیاتی را که معمولاً برای برنامههای Android رزرو شده است فراخوانی کند. اگر از آن استفاده میکنید، addJavaScriptInterface()
فقط در صفحات وب قرار دهید که تمام ورودیهای آن قابل اعتماد است. اگر ورودی نامعتبر مجاز باشد، جاوا اسکریپت نامعتبر ممکن است بتواند روشهای Android را در برنامه شما فراخوانی کند. به طور کلی، توصیه میکنیم که addJavaScriptInterface()
فقط در معرض جاوا اسکریپت قرار دهید که در APK برنامه شما موجود است.
اگر برنامه شما با WebView
به داده های حساس دسترسی پیدا می کند، از روش clearCache()
برای حذف فایل های ذخیره شده محلی استفاده کنید. همچنین میتوانید از هدرهای سمت سرور، مانند no-store
استفاده کنید تا نشان دهید که یک برنامه نباید محتوای خاصی را در حافظه پنهان نگه دارد.
دستگاههایی که پلتفرمهای قدیمیتر از Android 4.4 (سطح API 19) را اجرا میکنند، از نسخهای از webkit
استفاده میکنند که دارای تعدادی مشکلات امنیتی است. به عنوان یک راه حل، اگر برنامه شما در این دستگاه ها اجرا می شود، باید تأیید کند که اشیاء WebView
فقط محتوای مورد اعتماد را نمایش می دهند. برای اطمینان از اینکه برنامه شما در معرض آسیبپذیریهای احتمالی در SSL نیست، از شیء Provider
امنیتی قابل بهروزرسانی همانطور که در بهروزرسانی ارائهدهنده امنیت خود توضیح داده شده است برای محافظت در برابر سوء استفادههای SSL استفاده کنید. اگر برنامه شما باید محتوا را از وب باز ارائه کند، ارائه دهنده خود را در نظر بگیرید تا بتوانید آن را با آخرین وصله های امنیتی به روز نگه دارید.
درخواست های اعتبار
درخواست های اعتبار یک بردار برای حمله هستند. در اینجا چند نکته وجود دارد که به شما کمک می کند تا درخواست های اعتبارنامه را در برنامه های Android خود ایمن تر کنید.
قرار گرفتن در معرض اعتبار را به حداقل برسانید
- از درخواست های غیرضروری اعتبار خودداری کنید . برای آشکارتر کردن حملات فیشینگ و احتمال موفقیت کمتر، تعداد درخواست اعتبار کاربر را به حداقل برسانید. در عوض، از یک نشانه مجوز استفاده کنید و آن را بازخوانی کنید. فقط حداقل مقدار اطلاعات اعتبار لازم برای احراز هویت و مجوز را درخواست کنید.
- اعتبارنامه ها را ایمن ذخیره کنید . از Credential Manager برای فعال کردن احراز هویت بدون رمز عبور با استفاده از کلیدهای عبور یا برای پیادهسازی ورود به سیستم فدرال با استفاده از طرحهایی مانند ورود با Google استفاده کنید. اگر باید از احراز هویت رمز عبور سنتی استفاده کنید، شناسههای کاربری و رمزهای عبور را در دستگاه ذخیره نکنید. در عوض، احراز هویت اولیه را با استفاده از نام کاربری و رمز عبور ارائه شده توسط کاربر انجام دهید، و سپس از یک توکن مجوز مختص به سرویس کوتاه مدت استفاده کنید.
- محدوده مجوزها را محدود کنید . برای کاری که فقط به محدوده محدودتری نیاز دارد، مجوزهای گسترده درخواست نکنید.
- محدود کردن نشانه های دسترسی از عملیات توکن های کوتاه مدت و تماس های API استفاده کنید.
- محدود کردن نرخ احراز هویت احراز هویت سریع و پی در پی یا درخواست های مجوز می تواند نشانه ای از حمله brute-force باشد. این نرخها را به یک فرکانس معقول محدود کنید و در عین حال امکان تجربه اپلیکیشن کاربردی و کاربرپسند را فراهم کنید.
از احراز هویت امن استفاده کنید
- پیاده سازی کلیدهای عبور کلیدهای عبور را به عنوان ارتقای ایمن تر و کاربرپسندتر به گذرواژه ها فعال کنید.
- بیومتریک اضافه کنید برای امنیت بیشتر، امکان استفاده از احراز هویت بیومتریک مانند اثر انگشت یا تشخیص چهره را ارائه دهید.
- از ارائه دهندگان هویت فدرال استفاده کنید . Credential Manager از ارائه دهندگان احراز هویت فدرال مانند Sign in with Google پشتیبانی می کند.
- رمزگذاری ارتباطات از HTTPS و فناوریهای مشابه برای اطمینان از محافظت از دادههایی که برنامه شما از طریق شبکه ارسال میکند، استفاده کنید.
مدیریت امن حساب را تمرین کنید
- با استفاده از
AccountManager
به سرویس هایی متصل شوید که برای چندین برنامه قابل دسترسی هستند. از کلاسAccountManager
برای فراخوانی یک سرویس مبتنی بر ابر استفاده کنید و رمزهای عبور را در دستگاه ذخیره نکنید. - پس از استفاده از
AccountManager
برای بازیابیAccount
، قبل از ارسال هر گونه اعتبار، ازCREATOR
استفاده کنید تا سهواً اعتبار را به برنامه اشتباهی منتقل نکنید. - اگر اعتبارنامهها فقط توسط برنامههایی که شما ایجاد میکنید استفاده میشوند، میتوانید برنامهای را که با استفاده از
checkSignatures
AccountManager
دسترسی دارد، تأیید کنید. از طرف دیگر، اگر فقط یک برنامه از اعتبار استفاده می کند، ممکن است ازKeyStore
برای ذخیره سازی استفاده کنید.
هوشیار باشید
- کد خود را به روز نگه دارید . حتماً کد منبع خود را بهروزرسانی کنید، از جمله کتابخانههای شخص ثالث و وابستگیها، تا از آخرین آسیبپذیریها محافظت کنید.
- نظارت بر فعالیت های مشکوک به دنبال سوء استفاده بالقوه، مانند الگوهای سوء استفاده از مجوز باشید.
- کد خود را حسابرسی کنید برای بررسی مشکلات احتمالی درخواست اعتبارنامه، بررسیهای امنیتی منظمی را در برابر پایگاه کد خود انجام دهید.
مدیریت کلید API
کلیدهای API جزء حیاتی بسیاری از برنامههای اندروید هستند که به آنها امکان دسترسی به خدمات خارجی و انجام عملکردهای ضروری مانند اتصال به خدمات نقشهبرداری، احراز هویت و خدمات آبوهوا را میدهند. با این حال، افشای این کلیدهای حساس می تواند عواقب شدیدی از جمله نقض داده ها، دسترسی غیرمجاز و زیان های مالی داشته باشد. برای جلوگیری از چنین سناریوهایی، توسعهدهندگان باید استراتژیهای ایمن را برای مدیریت کلیدهای API در طول فرآیند توسعه پیادهسازی کنند.
برای محافظت از سرویس ها در برابر سوء استفاده، کلیدهای API باید به دقت محافظت شوند. برای ایمن کردن اتصال بین برنامه و سرویسی که از کلید API استفاده می کند، باید دسترسی به API را ایمن کنید. هنگامی که برنامه شما کامپایل شده است و کد منبع برنامه شما شامل کلیدهای API است، این امکان برای مهاجم وجود دارد که برنامه را دیکامپایل کند و این منابع را پیدا کند.
این بخش برای دو گروه از توسعه دهندگان اندروید در نظر گرفته شده است: کسانی که با تیم های زیرساخت در خط لوله تحویل مداوم خود کار می کنند و کسانی که برنامه های مستقل را در فروشگاه Play مستقر می کنند. این بخش بهترین روشها را برای نحوه کار با کلیدهای API نشان میدهد تا برنامه شما بتواند به طور ایمن با سرویسها ارتباط برقرار کند.
تولید و ذخیره سازی
توسعه دهندگان باید ذخیره سازی کلید API را به عنوان یک جزء مهم حفاظت از داده ها و حریم خصوصی کاربر با استفاده از رویکرد دفاعی عمیق در نظر بگیرند.
ذخیره سازی کلید قوی
برای امنیت بهینه مدیریت کلید، از Android Keystore استفاده کنید و کلیدهای ذخیره شده را با استفاده از ابزار قوی مانند Tink Java رمزگذاری کنید.
حذف کنترل منبع
هرگز کلیدهای API را در مخزن کد منبع خود قرار ندهید. افزودن کلیدهای API به کد منبع خطر قرار گرفتن کلیدها در مخازن عمومی، نمونههای کد مشترک و فایلهای به اشتراک گذاشته شده تصادفی را به همراه دارد. در عوض، از پلاگین های Gradle مانند Secrets-gradle-Plugin برای کار با کلیدهای API در پروژه خود استفاده کنید.
کلیدهای محیطی خاص
در صورت امکان، از محیط های توسعه، آزمایش و تولید کلیدهای API جداگانه استفاده کنید. از کلیدهای محیطی خاص برای جداسازی هر محیط استفاده کنید، که خطر افشای داده های تولید را کاهش می دهد و به شما امکان می دهد کلیدهای در معرض خطر را بدون تأثیر بر محیط تولید خود غیرفعال کنید.
استفاده و کنترل دسترسی
اقدامات کلیدی API امن برای محافظت از API و کاربران شما ضروری است. در اینجا نحوه آماده سازی کلیدهای خود برای امنیت مطلوب آورده شده است:
- ایجاد کلیدهای منحصر به فرد برای هر برنامه : از کلیدهای API جداگانه برای هر برنامه برای کمک به شناسایی و جداسازی دسترسی به خطر افتاده استفاده کنید.
- محدودیتهای IP را اعمال کنید : در صورت امکان، استفاده از کلید API را به آدرسها یا محدودههای IP خاص محدود کنید.
- محدود کردن استفاده از کلید برنامه تلفن همراه : استفاده از کلید API را به برنامههای تلفن همراه خاص با بستهبندی آنها با کلید یا با استفاده از گواهیهای برنامه محدود کنید.
- ثبت و نظارت بر فعالیتهای مشکوک : مکانیسمهای ثبت و نظارت بر استفاده از API را برای شناسایی فعالیتهای مشکوک و جلوگیری از سوء استفاده احتمالی پیادهسازی کنید.
توجه : سرویس شما باید ویژگی هایی برای محدود کردن کلیدها به یک بسته یا پلتفرم خاص ارائه دهد. به عنوان مثال، Google Maps API دسترسی کلید را با نام بسته و کلید امضا محدود می کند.
OAuth 2.0 چارچوبی برای مجوز دسترسی به منابع فراهم می کند. استانداردهایی را برای نحوه تعامل کلاینتها و سرورها تعریف میکند و اجازه میدهد تا مجوز امن را دریافت کنند. میتوانید از OAuth 2.0 برای محدود کردن استفاده از کلید API به کلاینتهای خاص استفاده کنید و دامنه دسترسی را طوری تعریف کنید که هر کلید API فقط حداقل سطح دسترسی لازم برای هدف مورد نظر خود را داشته باشد.
چرخش کلید و انقضا
برای کاهش خطر دسترسی غیرمجاز از طریق آسیبپذیریهای کشفنشده API، مهم است که کلیدهای API را به طور منظم بچرخانید. استاندارد ISO 27001 یک چارچوب انطباق را برای تعداد دفعات انجام چرخش کلید تعریف می کند. برای اکثر موارد، یک دوره چرخش کلید بین 90 روز تا 6 ماه باید کافی باشد. پیادهسازی یک سیستم مدیریت کلید قوی میتواند به شما در سادهسازی این فرآیندها کمک کند و کارایی نیازهای چرخش کلید و انقضا را بهبود بخشد.
بهترین شیوه های عمومی
- استفاده از SSL/HTTPS : همیشه از ارتباط HTTPS برای رمزگذاری درخواست های API خود استفاده کنید.
- پین کردن گواهی : برای یک لایه امنیتی بیشتر، می توانید پین کردن گواهی را برای بررسی اینکه کدام گواهینامه معتبر در نظر گرفته می شود، در نظر بگیرید.
- اعتبارسنجی و پاکسازی ورودی کاربر : ورودی کاربر را تأیید و پاکسازی کنید تا از حملات تزریقی که میتوانند کلیدهای API را در معرض دید قرار دهند، جلوگیری کنید.
- بهترین شیوه های امنیتی را دنبال کنید : بهترین شیوه های امنیتی عمومی را در فرآیند توسعه خود پیاده کنید، از جمله تکنیک های کدگذاری ایمن، بررسی کد و اسکن آسیب پذیری ها.
- مطلع بمانید : در مورد آخرین تهدیدات امنیتی و بهترین شیوه ها برای مدیریت کلید API به روز باشید.
- SDK ها به روز : مطمئن شوید که SDK ها و کتابخانه های شما به آخرین نسخه به روز شده اند.
رمزنگاری
اندروید علاوه بر ارائه جداسازی داده ها، پشتیبانی از رمزگذاری کامل سیستم فایل و ارائه کانال های ارتباطی امن، طیف گسترده ای از الگوریتم ها را برای محافظت از داده ها با استفاده از رمزنگاری ارائه می دهد.
بدانید که نرم افزار شما از کدام ارائه دهندگان امنیتی Java Cryptography Architecture (JCA) استفاده می کند. سعی کنید از بالاترین سطح پیاده سازی چارچوب از قبل موجود استفاده کنید که می تواند مورد استفاده شما را پشتیبانی کند. در صورت وجود، از ارائه دهندگان ارائه شده توسط Google به ترتیب مشخص شده توسط Google استفاده کنید.
اگر نیاز به بازیابی ایمن یک فایل از یک مکان شبکه شناخته شده دارید، یک URI ساده HTTPS ممکن است کافی باشد و نیازی به دانش رمزنگاری نداشته باشد. اگر به یک تونل امن نیاز دارید، به جای نوشتن پروتکل خود، از HttpsURLConnection
یا SSLSocket
استفاده کنید. اگر از SSLSocket
استفاده می کنید، توجه داشته باشید که تأیید نام میزبان را انجام نمی دهد. هشدارهای مربوط به استفاده مستقیم از SSLSocket
را ببینید.
اگر متوجه شدید که باید پروتکل خود را پیاده سازی کنید، الگوریتم های رمزنگاری خود را پیاده سازی نکنید. از الگوریتم های رمزنگاری موجود، مانند پیاده سازی های AES و RSA ارائه شده در کلاس Cipher
استفاده کنید. علاوه بر این، بهترین شیوه ها را دنبال کنید:
- از AES 256 بیتی برای اهداف تجاری استفاده کنید. (اگر در دسترس نیست، از AES 128 بیتی استفاده کنید.)
- برای رمزنگاری منحنی بیضی (EC) از اندازه کلید عمومی 224 یا 256 بیتی استفاده کنید.
- بدانید چه زمانی از حالت های بلوک CBC، CTR یا GCM استفاده کنید.
- از استفاده مجدد IV/counter در حالت CTR اجتناب کنید. مطمئن شوید که از نظر رمزنگاری تصادفی هستند.
- هنگام استفاده از رمزگذاری، یکپارچگی را با استفاده از حالت CBC یا CTR با یکی از عملکردهای زیر پیاده سازی کنید:
- HMAC-SHA1
- HMAC-SHA-256
- HMAC-SHA-512
- حالت GCM
از یک مولد اعداد تصادفی امن، SecureRandom
، برای مقداردهی اولیه کلیدهای رمزنگاری تولید شده توسط KeyGenerator
استفاده کنید. استفاده از کلیدی که با مولد اعداد تصادفی ایمن تولید نمی شود، قدرت الگوریتم را به میزان قابل توجهی ضعیف می کند و ممکن است امکان حملات آفلاین را فراهم کند.
اگر نیاز به ذخیره کلید برای استفاده مکرر دارید، از مکانیزمی مانند KeyStore
استفاده کنید که ذخیره طولانی مدت و بازیابی کلیدهای رمزنگاری را فراهم می کند.
ارتباطات بین فرآیندی
برخی از برنامهها تلاش میکنند IPC را با استفاده از تکنیکهای سنتی لینوکس مانند سوکتهای شبکه و فایلهای مشترک پیادهسازی کنند. با این حال، به جای آن توصیه می کنیم از عملکرد سیستم Android برای IPC مانند Intent
، Binder
یا Messenger
with a Service
و BroadcastReceiver
استفاده کنید. مکانیسمهای IPC Android به شما امکان میدهند هویت برنامه متصل به IPC خود را تأیید کنید و خطمشی امنیتی را برای هر مکانیزم IPC تنظیم کنید.
بسیاری از عناصر امنیتی در مکانیسم های IPC مشترک هستند. اگر مکانیسم IPC شما برای استفاده توسط برنامه های دیگر در نظر گرفته نشده است، ویژگی android:exported
در عنصر مانیفست مؤلفه مانند عنصر <service>
روی false
تنظیم کنید. این برای برنامههایی مفید است که از چندین فرآیند در یک UID تشکیل شدهاند یا اگر در اواخر توسعه تصمیم بگیرید که واقعاً نمیخواهید عملکرد را به عنوان IPC نشان دهید، اما نمیخواهید کد را بازنویسی کنید مفید است.
اگر IPC شما برای سایر برنامه ها قابل دسترسی است، می توانید با استفاده از عنصر <permission>
یک خط مشی امنیتی اعمال کنید. اگر IPC بین برنامههایی است که متعلق به شما هستند و با همان کلید امضا شدهاند، از مجوز signature-level
در android:protectionLevel
استفاده کنید.
مقاصد
برای فعالیتها و گیرندههای پخش، Intent مکانیسم ترجیحی برای IPC ناهمزمان در Android است. بسته به نیازهای برنامه خود، ممکن است از sendBroadcast
، sendOrderedBroadcast
یا یک هدف صریح برای یک جزء برنامه خاص استفاده کنید. برای اهداف امنیتی، مقاصد صریح ترجیح داده می شوند.
احتیاط : اگر از قصدی برای اتصال به **Service**
استفاده می کنید، از یک قصد صریح برای ایمن نگه داشتن برنامه خود استفاده کنید. استفاده از یک قصد ضمنی برای شروع یک سرویس یک خطر امنیتی است، زیرا نمی توانید مطمئن باشید که چه سرویسی به این هدف پاسخ می دهد و کاربر نمی تواند ببیند کدام سرویس شروع می شود. با شروع Android 5.0 (سطح API 21)، اگر شما **bindService()**
با یک هدف ضمنی فراخوانی کنید، سیستم یک استثنا ایجاد می کند.
توجه داشته باشید که پخش های سفارش داده شده می توانند توسط گیرنده مصرف شوند، بنابراین ممکن است به همه برنامه ها تحویل داده نشوند. اگر قصدی را ارسال می کنید که باید به یک گیرنده خاص تحویل داده شود، باید از یک قصد صریح استفاده کنید که گیرنده را با نام اعلام می کند.
فرستنده های یک قصد می توانند تأیید کنند که گیرنده با مشخص کردن مجوز غیر تهی با تماس روش ، مجوز دارد. فقط برنامه های با آن مجوز هدف را دریافت می کنند. اگر داده های موجود در یک قصد پخش ممکن است حساس باشد ، در نظر بگیرید که از مجوز استفاده کنید تا اطمینان حاصل کنید که برنامه های مخرب نمی توانند برای دریافت این پیام ها بدون مجوز مناسب ثبت نام کنند. در چنین شرایطی ، شما همچنین ممکن است به جای افزایش پخش ، به طور مستقیم از گیرنده استفاده کنید.
توجه : فیلترهای قصد از ویژگی های امنیتی نیستند. مؤلفه ها را می توان با اهداف صریح فراخوانی کرد و ممکن است داده هایی نداشته باشد که مطابق با فیلتر هدف باشد. برای تأیید اینکه به درستی برای گیرنده ، سرویس یا فعالیت فراخوانی شده فرمت شده است ، اعتبار ورودی را در گیرنده قصد خود انجام دهید.
خدمات
اغلب از Service
برای تأمین قابلیت های دیگر برنامه های کاربردی استفاده می شود. هر کلاس خدمات باید در پرونده آشکار خود یک اعلامیه <service>
مربوطه داشته باشد.
به طور پیش فرض ، خدمات صادر نمی شوند و توسط هیچ برنامه دیگری قابل استفاده نیستند. با این حال ، اگر فیلترهای قصد را به اعلامیه خدمات اضافه کنید ، به طور پیش فرض صادر می شود. بهتر است اگر صریحاً android:exported
برای اطمینان از این که روشی را که قصد دارید رفتار می کند. خدمات همچنین می توانند با استفاده از ویژگی android:permission
محافظت شوند. با این کار ، سایر برنامه ها باید یک عنصر مربوط به <uses-permission>
را در مانیفست خود اعلام کنند تا بتوانند به سرویس شروع ، متوقف یا اتصال دهند.
توجه : اگر برنامه شما Android 5.0 (API سطح 21) یا بالاتر را هدف قرار داده است ، از **JobScheduler**
برای اجرای خدمات پس زمینه استفاده کنید.
یک سرویس می تواند از تماس های IPC جداگانه که با مجوز در آن ساخته می شود ، محافظت کند. این کار با فراخوانی checkCallingPermission()
قبل از اجرای اجرای تماس انجام می شود. توصیه می کنیم از مجوزهای اعلامی در مانیفست استفاده کنید ، زیرا این موارد کمتر مستعد نظارت هستند.
احتیاط : مجوزهای مشتری و سرور را اشتباه نگیرید. اطمینان حاصل کنید که برنامه نامیده شده مجوزهای مناسبی دارد و تأیید کنید که شما همان مجوزها را به برنامه فراخوانی اعطا می کنید.
رابط های چسبنده و مسنجر
استفاده از Binder
یا Messenger
مکانیزم ارجح برای IPC سبک RPC در Android است. آنها رابط های تعریف شده ای را ارائه می دهند که در صورت لزوم احراز هویت متقابل نقاط پایانی را امکان پذیر می کنند.
توصیه می کنیم رابط های برنامه خود را به گونه ای طراحی کنید که نیازی به بررسی مجوزهای خاص رابط ندارد. اشیاء Binder
و Messenger
در آشکار برنامه اعلام نمی شوند ، بنابراین شما نمی توانید مجوزهای اعلامی را مستقیماً برای آنها اعمال کنید. آنها به طور کلی مجوزهای اعلام شده در برنامه را برای Service
یا Activity
که در آن انجام می شود ، به ارث می برند. اگر در حال ایجاد رابط کاربری هستید که نیاز به تأیید اعتبار و/یا کنترل دسترسی داشته باشد ، باید صریحاً آن کنترل ها را به عنوان کد در Binder
یا Messenger
اضافه کنید.
اگر رابط کاربری را ارائه می دهید که به کنترل دسترسی نیاز دارد ، از checkCallingPermission()
استفاده کنید تا تأیید کنید که آیا تماس گیرنده مجوز لازم را دارد یا خیر. این امر به ویژه قبل از دسترسی به یک سرویس به نمایندگی از تماس گیرنده مهم است ، زیرا هویت برنامه شما به سایر رابط ها منتقل می شود. اگر از رابط ارائه شده توسط یک Service
استفاده می کنید ، اگر اجازه دسترسی به سرویس داده شده را ندارید bindService()
می تواند شکست بخورد. اگر نیاز دارید که یک فرآیند خارجی با برنامه خود تعامل داشته باشد اما مجوزهای لازم برای انجام این کار را ندارد ، می توانید از روش clearCallingIdentity()
استفاده کنید. این روش تماس را به رابط برنامه شما انجام می دهد که گویی برنامه شما به جای تماس گیرنده خارجی ، خود را در حال برقراری تماس می داند. شما می توانید بعداً مجوزهای تماس گیرنده را با روش restoreCallingIdentity()
بازیابی کنید.
برای اطلاعات بیشتر در مورد انجام IPC با یک سرویس ، به خدمات محدود مراجعه کنید.
گیرنده های پخش شده
یک BroadcastReceiver
درخواست های ناهمزمان را که توسط یک Intent
آغاز می شود ، انجام می دهد.
به طور پیش فرض ، گیرنده ها صادر می شوند و توسط هر برنامه دیگری قابل استفاده هستند. اگر BroadcastReceiver
شما برای استفاده توسط سایر برنامه ها در نظر گرفته شده است ، ممکن است بخواهید مجوزهای امنیتی را برای گیرنده ها با استفاده از عنصر <receiver>
در مانیفست برنامه اعمال کنید. این امر مانع از ارسال مجوزهای مناسب برای ارسال قصد به BroadcastReceiver
می شود.
امنیت با کد بارگیری پویا
ما به شدت کد بارگیری را از خارج از برنامه APK شما دلسرد می کنیم. انجام این کار به دلیل تزریق کد یا دستکاری کد ، احتمال سازش برنامه را به میزان قابل توجهی افزایش می دهد. همچنین پیچیدگی در مورد مدیریت نسخه و آزمایش برنامه ها را اضافه می کند - و می تواند تأیید رفتار یک برنامه را غیرممکن کند ، بنابراین ممکن است در برخی از محیط ها ممنوع باشد.
اگر برنامه شما به صورت پویا کد را بارگیری می کند ، مهمترین نکته باید در نظر داشته باشید این است که کد بارگیری پویا با همان مجوزهای امنیتی مانند برنامه APK اجرا می شود. کاربر تصمیم می گیرد برنامه خود را بر اساس هویت شما نصب کند و کاربر انتظار دارد که شما هر کد را در برنامه اجرا کنید ، از جمله کدی که به صورت پویا بارگیری می شود.
بسیاری از برنامه ها سعی می کنند کد را از مکانهای ناامن ، مانند بارگیری از شبکه از طریق پروتکل های رمزگذاری نشده یا از مکانهای مربوط به جهان مانند ذخیره سازی خارجی بارگیری کنند. این مکان ها می توانند به کسی در شبکه اجازه دهند محتوا را در ترانزیت یا برنامه دیگری در دستگاه کاربر تغییر دهد تا محتوای موجود در دستگاه را تغییر دهد. از طرف دیگر ، ماژول هایی که مستقیماً در APK شما گنجانده شده اند نمی توانند توسط سایر برنامه ها اصلاح شوند. این درست است که آیا کد یک کتابخانه بومی است یا یک کلاس با استفاده از DexClassLoader
بارگیری می شود.
امنیت در یک ماشین مجازی
Dalvik ماشین مجازی Runtime Android (VM) است. Dalvik به طور خاص برای Android ساخته شده است ، اما بسیاری از نگرانی های مربوط به کد امن در سایر ماشین های مجازی نیز در مورد Android اعمال می شود. به طور کلی ، نیازی نیست که خود را با مسائل امنیتی مربوط به ماشین مجازی نگران کنید. برنامه شما در یک محیط امن ماسهبازی اجرا می شود ، بنابراین سایر فرآیندهای موجود در سیستم نمی توانند به کد یا داده های خصوصی شما دسترسی پیدا کنند.
اگر علاقه مند به کسب اطلاعات بیشتر در مورد امنیت ماشین مجازی هستید ، خود را با برخی از ادبیات موجود در مورد این موضوع آشنا کنید. دو مورد از منابع محبوب ترین عبارتند از:
این سند بر مناطقی که دارای اندرویدی خاص یا متفاوت از سایر محیط های VM هستند ، تمرکز دارد. برای توسعه دهندگان که با برنامه نویسی VM در محیط های دیگر تجربه شده اند ، دو موضوع گسترده وجود دارد که ممکن است در مورد نوشتن برنامه های Android متفاوت باشد:
- برخی از ماشین های مجازی ، مانند زمان اجرا JVM یا .NET ، به عنوان یک مرز امنیتی عمل می کنند و کد را از قابلیت های سیستم عامل اساسی جدا می کنند. در Android ، Dalvik VM یک مرز امنیتی نیست - ماسه جعبه برنامه در سطح سیستم عامل اجرا می شود ، بنابراین Dalvik می تواند بدون هیچ گونه محدودیت امنیتی با کد بومی در همان برنامه ارتباط برقرار کند.
- با توجه به ذخیره سازی محدود در دستگاه های تلفن همراه ، توسعه دهندگان معمول است که بخواهند برنامه های مدولار بسازند و از بارگیری کلاس پویا استفاده کنند. هنگام انجام این کار ، هر دو منبع را در جایی که منطق برنامه خود را بازیابی می کنید و در کجا آن را به صورت محلی ذخیره می کنید ، در نظر بگیرید. از بارگیری کلاس پویا از منابعی که تأیید نشده اند ، مانند منابع شبکه ناامن یا ذخیره خارجی استفاده نکنید ، زیرا ممکن است این کد اصلاح شود تا شامل رفتار مخرب شود.
امنیت در کد بومی
به طور کلی ، ما توصیه می کنیم به جای استفاده از کد بومی با Android NDK ، از Android SDK برای توسعه برنامه استفاده کنید. برنامه های ساخته شده با کد بومی پیچیده تر ، قابل حمل تر هستند و احتمالاً شامل خطاهای متداول فساد حافظه مانند سرریز بافر می شوند.
Android با استفاده از هسته لینوکس ساخته شده است و آشنایی با بهترین شیوه های امنیتی توسعه لینوکس در صورت استفاده از کد بومی بسیار مفید است. شیوه های امنیتی لینوکس فراتر از محدوده این سند نیست ، اما یکی از محبوب ترین منابع برنامه نویسی امن Howto - ایجاد نرم افزار ایمن است.
تفاوت مهمی بین Android و بیشتر محیط های لینوکس در ماسهبازی برنامه است. در Android ، کلیه برنامه ها در جعبه ماسه ای برنامه اجرا می شوند ، از جمله مواردی که با کد بومی نوشته شده اند. یک روش خوب برای فکر کردن در مورد آن برای توسعه دهندگان آشنا با لینوکس این است که بدانید به هر برنامه یک شناسه کاربر منحصر به فرد (UID) با مجوزهای بسیار محدود داده می شود. این موضوع با جزئیات بیشتر در مروری بر امنیت Android مورد بحث قرار می گیرد ، و حتی اگر از کد بومی استفاده می کنید ، باید با مجوزهای برنامه آشنا باشید.