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.
Intencja używana do uruchamiania nowego komponentu może być podawana na kilka sposobów, najczęściej jako zserializowana intencja w polu extras
lub za pomocą funkcji marshalingu do ciągu znaków i analizy. 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.
Złagodzenia
Zasadniczo nie udostępniaj funkcji związanych z przekierowywaniem ukrytych intencji. W przypadkach, w których jest to nieuniknione, zastosuj te metody zapobiegania:
- Odpowiednio odizoluj informacje z pakietu. Pamiętaj, aby sprawdzić lub usunąć flagi (
FLAG_GRANT_READ_URI_PERMISSION, FLAG_GRANT_WRITE_URI_PERMISSION, FLAG_GRANT_PERSISTABLE_URI_PERMISSION, and FLAG_GRANT_PREFIX_URI_PERMISSION
) oraz sprawdzić, dokąd jest przekierowywana intencja. W tym procesie może Ci pomócIntentSanitizer
. - Używaj obiektów
PendingIntent
. Zapobiega to eksportowaniu 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);
Domyślna ochrona
Android 16 wprowadza domyślne rozwiązanie zabezpieczające przed atakami polegającymi na przekierowywaniu.Intent
W większości przypadków aplikacje, które używają intencji, nie mają problemów ze zgodnością.
Rezygnacja z obsługi przekierowania intencji
Android 16 wprowadza nowy interfejs API, który umożliwia aplikacjom rezygnację z zabezpieczeń podczas uruchamiania. Może być to konieczne w niektórych przypadkach, gdy domyślne zachowanie zabezpieczeń zakłóca prawidłowe korzystanie z aplikacji.
W Androidzie 16 możesz zrezygnować z zabezpieczeń, używając metody removeLaunchSecurityProtection()
na obiekcie Intent
. Przykład:
val i = intent
val iSublevel: Intent? = i.getParcelableExtra("sub_intent")
iSublevel?.removeLaunchSecurityProtection() // Opt out from hardening
iSublevel?.let { startActivity(it) }
Typowe błędy
- Sprawdzanie, czy funkcja
getCallingActivity()
zwraca niepustą wartość. 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 niebezpiecznie intencję.
Jeśli Twoja aplikacja wykonuje oba z tych działań, system wykryje uruchomienie niebezpiecznej intencji i dojdzie do naruszenia zasad StrictMode
:
- Aplikacja rozpakowuje zagnieżdżoną intencję z elementów dodatkowych dostarczonej intencji.
- Aplikacja natychmiast uruchamia komponent aplikacji, używając tego zagnieżdżonego zamiaru, np. przekazując go do
startActivity()
,startService()
lubbindService()
.