تغییر مسیر قصد

دسته OWASP: MASVS-PLATFORM: پلتفرم تعامل

نمای کلی

تغییر مسیر قصد زمانی اتفاق می‌افتد که یک مهاجم بتواند تا حدی یا به طور کامل محتوای یک intent را که برای راه‌اندازی یک مؤلفه جدید در زمینه یک برنامه آسیب‌پذیر استفاده می‌شود، کنترل کند.

هدف مورد استفاده برای راه‌اندازی مولفه جدید می‌تواند به روش‌های مختلفی ارائه شود، معمولاً یا به صورت یک هدف سریالی در یک فیلد 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 بررسی کنند که یک intent به کجا هدایت می شود:

کاتلین

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);

اشتباهات رایج

  • بررسی اینکه getCallingActivity() یک مقدار غیر تهی را برمی گرداند. برنامه های مخرب می توانند مقدار تهی برای این تابع ارائه دهند.
  • با فرض اینکه checkCallingPermission() در همه زمینه ها کار می کند، یا زمانی که متد در واقع یک عدد صحیح را برمی گرداند یک استثنا ایجاد می کند.

ویژگی های اشکال زدایی

برای برنامه‌هایی که Android 12 (سطح API 31) یا بالاتر را هدف قرار می‌دهند، می‌توانید یک ویژگی اشکال‌زدایی را فعال کنید که در برخی موارد به شما کمک می‌کند تشخیص دهید که آیا برنامه شما راه‌اندازی ناایمن یک intent را انجام می‌دهد یا خیر.

اگر برنامه شما هر دو عملکرد زیر را انجام دهد، سیستم یک هدف ناامن را شناسایی می کند و یک نقض StrictMode رخ می دهد:

  • برنامه شما یک هدف تودرتو را از موارد اضافی یک هدف ارائه شده جدا می کند.
  • برنامه شما فوراً یک مؤلفه برنامه را با استفاده از آن هدف تودرتو، مانند ارسال intent به startActivity() ، startService() یا bindService() راه اندازی می کند.

منابع