OWASP-Kategorie: MASVS-PLATFORM: Plattforminteraktion
Übersicht
Eine Intent-Umleitung erfolgt, wenn ein Angreifer den Inhalt eines Intents, der zum Starten einer neuen Komponente im Kontext einer anfälligen Anwendung verwendet wird, teilweise oder vollständig kontrollieren kann.
Der Intent, mit dem die neue Komponente gestartet wird, kann auf verschiedene Arten angegeben werden. Am häufigsten wird er entweder als serialisierter Intent in einem extras
-Feld oder als String übergeben und geparst. Auch eine teilweise Kontrolle über Parameter kann zum gleichen Ergebnis führen.
Positiv beeinflussen
Die Auswirkungen können variieren. Ein Angreifer kann interne Funktionen in der angreifbaren Anwendung ausführen oder auf private Komponenten wie nicht exportierte ContentProvider-Objekte zugreifen.
Abwehrmaßnahmen
Zeigen Sie in der Regel keine Funktionen zur Weiterleitung verschachtelter Intents an. Wenn dies nicht möglich ist, wenden Sie die folgenden Maßnahmen zur Risikominderung an:
- Die gebündelten Informationen müssen ordnungsgemäß bereinigt werden. Denken Sie daran, Markierungen zu prüfen oder zu entfernen (
FLAG_GRANT_READ_URI_PERMISSION, FLAG_GRANT_WRITE_URI_PERMISSION, FLAG_GRANT_PERSISTABLE_URI_PERMISSION, and FLAG_GRANT_PREFIX_URI_PERMISSION
) und zu prüfen, wohin die Intent-Anfrage weitergeleitet wird.IntentSanitizer
kann Ihnen dabei helfen. - Verwenden Sie
PendingIntent
-Objekte. Dadurch wird verhindert, dass die Komponente exportiert wird, und der Intent der Zielaktion ist unveränderlich.
Apps können mithilfe von Methoden wie ResolveActivity
prüfen, wohin ein Intent weitergeleitet wird:
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);
}
Apps können IntentSanitizer
mit einer ähnlichen Logik wie der folgenden verwenden:
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);
Häufige Fehler
- Prüfen, ob
getCallingActivity()
einen Wert zurückgibt, der nicht null ist. Schädliche Apps sind in der Lage, dieser Funktion einen Nullwert zuzuführen. - Angenommen,
checkCallingPermission()
funktioniert in allen Kontexten oder die Methode löst eine Ausnahme aus, obwohl sie tatsächlich eine Ganzzahl zurückgibt.
Funktionen zur Fehlerbehebung
Für Apps, die auf Android 12 (API-Level 31) oder höher ausgerichtet sind, können Sie eine Fehlerbehebungsfunktion aktivieren, mit der Sie in einigen Fällen feststellen können, ob in Ihrer App ein unsicherer Start eines Intents ausgeführt wird.
Wenn Ihre App die folgenden beiden Aktionen ausführt, erkennt das System einen unsicheren Intent-Start und tritt ein StrictMode
-Verstoß auf:
- Ihre App entpackt einen verschachtelten Intent aus den Extras eines gesendeten Intents.
- Ihre App startet sofort eine App-Komponente mit dieser verschachtelten Absicht, z. B. indem die Absicht an
startActivity()
,startService()
oderbindService()
übergeben wird.