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 służąca do uruchomienia nowego komponentu może być podawana na kilka sposobów, najczęściej jako zserializowana intencja w polu extras
lub za pomocą serializacji 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
:
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);
}
Aplikacje mogą używać IntentSanitizer
zgodnie z zasadami podobnymi do tych:
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);
Domyślna ochrona
- Android 16 wprowadza domyślne rozwiązanie zabezpieczające przed atakami polegającymi na przekierowywaniu intencji.
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()
.