Intent yönlendirme

OWASP kategorisi: MASVS-PLATFORM: Platform Etkileşimi

Genel Bakış

Saldırgan, güvenlik açığı bulunan bir uygulama bağlamında yeni bir bileşeni başlatmak için kullanılan intent'in içeriğini kısmen veya tamamen kontrol edebildiğinde intent yönlendirmesi gerçekleşir.

Yeni bileşeni başlatmak için kullanılan amaç, en yaygın olarak extras alanında serileştirilmiş amaç olarak ya da bir dizeye yönlendirilip ayrıştırılmak üzere birkaç farklı şekilde sağlanabilir. Parametrelerin kısmi kontrol edilmesi de aynı sonuca yol açabilir.

Etki

Etki değişiklik gösterebilir. Bir saldırgan, güvenlik açığı içeren uygulamadaki dahili özellikleri yürütebilir veya dışa aktarılmayan ContentProvider nesneleri gibi gizli bileşenlere erişebilir.

Çözümler

Genel olarak, iç içe yerleştirilmiş intent'leri yönlendirmeyle ilgili özellikleri göstermeyin. Kaçınılmaz olduğu durumlarda aşağıdaki azaltma yöntemlerini uygulayın:

  • Paketlenmiş bilgileri uygun şekilde temizleyin. İşaretleri (FLAG_GRANT_READ_URI_PERMISSION, FLAG_GRANT_WRITE_URI_PERMISSION, FLAG_GRANT_PERSISTABLE_URI_PERMISSION, and FLAG_GRANT_PREFIX_URI_PERMISSION) kontrol etmeyi veya temizlemeyi ve intent'in nereye yönlendirildiğini kontrol etmeyi unutmayın. IntentSanitizer bu süreçte size yardımcı olabilir.
  • PendingIntent nesnelerini kullanın. Bu, bileşeninizin dışa aktarılmasını engeller ve hedef işlem niyetini değiştirilemez hale getirir.

Uygulamalar, ResolveActivity gibi yöntemler kullanarak bir intent'in nereye yönlendirildiğini kontrol edebilir:

Kotlin

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

Java

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

Uygulamalar, aşağıdakine benzer bir mantık kullanarak IntentSanitizer kullanabilir:

Kotlin

val intent = IntentSanitizer.Builder()
     .allowComponent("com.example.ActivityA")
     .allowData("com.example")
     .allowType("text/plain")
     .build()
     .sanitizeByThrowing(intent)

Java

Intent intent = new  IntentSanitizer.Builder()
     .allowComponent("com.example.ActivityA")
     .allowData("com.example")
     .allowType("text/plain")
     .build()
     .sanitizeByThrowing(intent);

Sık yapılan yanlışlar

  • getCallingActivity() öğesinin null olmayan bir değer döndürüp döndürmediği kontrol ediliyor. Kötü amaçlı uygulamalar bu işlev için null değer sağlayabilir.
  • checkCallingPermission() işlevinin tüm bağlamlarda çalıştığı veya yöntemin aslında bir tam sayı döndürdüğü halde istisna oluşturduğu varsayılır.

Hata ayıklama özellikleri

Android 12 (API düzeyi 31) veya sonraki sürümleri hedefleyen uygulamalarda, bazı durumlarda uygulamanızın güvenli olmayan bir intent başlatıp başlatmadığını tespit etmenize yardımcı olan bir hata ayıklama özelliğini etkinleştirebilirsiniz.

Uygulamanız aşağıdaki işlemlerin ikisini de gerçekleştirirse sistem güvenli olmayan bir intent başlatma işlemi algılar ve StrictMode ihlali meydana gelir:

  • Uygulamanız, gönderilen bir intent'in ekstralarından iç içe yerleştirilmiş bir intent'i paketten çıkarıyor.
  • Uygulamanız, bu iç içe yerleştirilmiş intent'i kullanarak hemen bir uygulama bileşeni başlatır (ör. intent'i startActivity(), startService() veya bindService()'ye iletme).

Kaynaklar