Przekierowanie intencji

Kategoria OWASP: MASVS-PLATFORM: Platform Interaction

Omówienie

Przekierowanie intencji występuje, gdy atakujący może częściowo lub całkowicie kontrolować zawartość intencji używanej do uruchamiania nowego komponentu w kontekście podatnej aplikacji.

Intencję używaną do uruchomienia nowego komponentu można przekazać na kilka sposobów – najczęściej jako zserializowaną intencję w polu extras lub utworzoną w ciągu znaków i przekształconą w analizę. Pełna kontrola parametrów może też prowadzić do tego samego wyniku.

Wpływ

Ich wpływ może być różny. Atakujący może wykonywać funkcje wewnętrzne w aplikacji z luką lub uzyskać dostęp do komponentów prywatnych, takich jak niewyeksportowane obiekty ContentProvider.

Środki zaradcze

Zasadniczo nie udostępniaj funkcji związanych z przekierowywaniem ukrytych intencji. W przypadkach, w których jest to nieuniknione, zastosuj te metody zapobiegania:

  • Prawidłowo zmodyfikuj pakiet informacji. Ważne jest, by sprawdzać i usuwać flagi (FLAG_GRANT_READ_URI_PERMISSION, FLAG_GRANT_WRITE_URI_PERMISSION, FLAG_GRANT_PERSISTABLE_URI_PERMISSION, and FLAG_GRANT_PREFIX_URI_PERMISSION) oraz sprawdzać, dokąd są przekierowywani intencje. IntentSanitizer może pomóc w tym procesie.
  • Używaj obiektów PendingIntent. Zapobiega to wyeksportowaniu komponentu i uniemożliwia zmianę intencji działania docelowego.

Aplikacje mogą sprawdzać, dokąd jest przekierowywana intencja, korzystając z takich metod jak: ResolveActivity:

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

Aplikacje mogą używać IntentSanitizer zgodnie z zasadami podobnymi do tych:

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

Typowe błędy

  • Sprawdzanie, czy getCallingActivity() zwraca wartość niepustą. Złośliwe aplikacje mogą dostarczyć pustą wartość dla tej funkcji.
  • Zakładamy, że checkCallingPermission() działa we wszystkich kontekstach lub że metoda zwraca wyjątek, gdy zwraca liczbę całkowitą.

Funkcje debugowania

W przypadku aplikacji kierowanych na Androida 12 (poziom interfejsu API 31) lub nowszego możesz włączyć funkcję debugowania, która w niektórych przypadkach pomoże Ci wykryć, czy aplikacja uruchamia niebezpieczny intencję.

Jeśli Twoja aplikacja wykonuje oba z tych działań, system wykryje uruchomienie niebezpiecznej intencji i dojdzie do naruszenia zasad StrictMode:

  • Aplikacja oddziela zagnieżdżoną intencję od dodatkowych elementów intencji.
  • Aplikacja natychmiast uruchamia komponent aplikacji, używając tego zagnieżdżonego zamiaru, np. przekazując go do startActivity(), startService() lub bindService().

Materiały