دسته OWASP: MASVS-PLATFORM: تعامل پلاتفرم
نمای کلی
هدایت هدف زمانی رخ میدهد که مهاجم بتواند محتوای هدف مورد استفاده برای راهاندازی عنصر جدید در زمینه برنامه آسیبپذیر را بهطور کامل یا جزئی کنترل کند.
هدف استفادهشده برای راهاندازی مؤلفه جدید میتواند به چند روش ارائه شود،
معمولاً یا بهعنوان هدف سریالسازیشده در فیلد extras، یا
بهصورت رشتهای مرتب و تجزیه شود. کنترل جزئی پارامترها نیز میتواند به نتیجه یکسانی منجر شود.
تأثیر
تأثیر آن میتواند متفاوت باشد. مهاجم ممکن است ویژگیهای داخلی را در برنامه آسیبپذیر اجرا کند یا ممکن است به عناصر خصوصی مثل اشیای ContentProvider صادرنشده دسترسی پیدا کند.
اقدامات کاهشی
بهطورکلی، ویژگیهای مربوط به هدایت مجدد هدفهای تو در تو را آشکار نکنید. در مواردی که اجتنابناپذیر است، روشهای کاهشی زیر را اعمال کنید:
- اطلاعات دستهبندیشده را بهدرستی پاکسازی کنید. مهم است که پرچمها (
FLAG_GRANT_READ_URI_PERMISSION, FLAG_GRANT_WRITE_URI_PERMISSION, FLAG_GRANT_PERSISTABLE_URI_PERMISSION, and FLAG_GRANT_PREFIX_URI_PERMISSION) را بررسی یا پاک کنید و بررسی کنید که قصد به کجا هدایت میشود. IntentSanitizerمیتواند در این فرایند کمک کند. - از
PendingIntentشیء استفاده کنید. این کار از صادر شدن مؤلفهتان جلوگیری میکند و هدف کنش را تغییرناپذیر میکند.
برنامهها میتوانند بااستفاده از روشهایی مثل
ResolveActivity بررسی کنند هدف در کجا هدایت میشود:
کاتلین
val intent = getIntent()
// Get the component name of the nested intent.
val forward = intent.getParcelableExtra<Parcelable>("key") as Intent
val name: ComponentName = forward.resolveActivity(packageManager)
// Check that the package name and class name contain the expected values.
if (name.packagename == "safe_package" && name.className == "safe_class") {
// Redirect the nested intent.
startActivity(forward)
}
جاوا
Intent intent = getIntent()
// Get the component name of the nested intent.
Intent forward = (Intent) intent.getParcelableExtra("key");
ComponentName name = forward.resolveActivity(getPackageManager());
// Check that the package name and class name contain the expected values.
if (name.getPackageName().equals("safe_package") &&
name.getClassName().equals("safe_class")) {
// Redirect the nested intent.
startActivity(forward);
}
برنامهها میتوانند از IntentSanitizer بااستفاده از منطقی مشابه
موارد زیر استفاده کنند:
کاتلین
val intent = IntentSanitizer.Builder()
.allowComponent("com.example.ActivityA")
.allowData("com.example")
.allowType("text/plain")
.build()
.sanitizeByThrowing(intent)
جاوا
Intent intent = new IntentSanitizer.Builder()
.allowComponent("com.example.ActivityA")
.allowData("com.example")
.allowType("text/plain")
.build()
.sanitizeByThrowing(intent);
محافظت پیشفرض
Android 16 راهحل سختسازی امنیتی پیشفرضی را برای Intent
بهرهجوییهای هدایت مجدد معرفی میکند. در اکثر موارد، برنامههایی که از هدف استفاده میکنند معمولاً با
مشکلات سازگاری مواجه نمیشوند.
انصراف دادن از مدیریت هدایت هدف
Android 16 میانای برنامهسازی کاربردی جدیدی را معرفی میکند که به برنامهها اجازه میدهد از محافظتهای امنیتی راهاندازی انصراف دهند. این کار ممکن است در موارد خاصی که رفتار امنیتی پیشفرض با موارد استفاده قانونی برنامه تداخل دارد ضروری باشد.
در Android 16، میتوانید بااستفاده از روش
removeLaunchSecurityProtection() در شیء Intent، از محافظتهای امنیتی انصراف دهید. برای مثال:
val i = intent
val iSublevel: Intent? = i.getParcelableExtra("sub_intent")
iSublevel?.removeLaunchSecurityProtection() // Opt out from hardening
iSublevel?.let { startActivity(it) }
اشتباهات رایج
- درحال بررسی اینکه آیا
getCallingActivity()مقدار غیرتهی برمیگرداند یا نه. برنامههای مخرب میتوانند برای این تابع مقدار تهی ارائه دهند. - با این فرض که
checkCallingPermission()در همه زمینهها کار میکند، یا اینکه وقتی روش درواقع عدد صحیح برمیگرداند، استثنا ایجاد میکند.
ویژگیهای اشکالزدایی
برای برنامههایی که Android 12 (سطح API 31) یا بالاتر را هدفیابی میکنند، میتوانید ویژگی اشکالزدایی را فعال کنید که در برخی موارد به شما کمک میکند تشخیص دهید آیا برنامهتان راهاندازی ناامن هدف انجام میدهد یا نه.
اگر برنامه شما هر دو اقدام زیر را انجام دهد، سیستم راهاندازی هدف ناامن را تشخیص میدهد و نقض StrictMode رخ میدهد:
- برنامه شما هدف تو در تو را از موارد اضافی هدف تحویلشده باز میکند.
- برنامه شما بلافاصله مؤلفه برنامه را بااستفاده از آن هدف تودرتو شروع میکند، برای مثال
هدف را به
startActivity()،startService()، یاbindService()ارسال میکند.