Redirection des intents

Catégorie OWASP : MASVS-PLATFORM : interaction avec la plate-forme

Présentation

Une redirection d'intent se produit lorsqu'un pirate informatique parvient à contrôler partiellement ou entièrement le contenu d'un intent utilisé pour lancer un nouveau composant dans le contexte d'une application vulnérable.

L'intent utilisé pour lancer le nouveau composant peut être fourni de plusieurs manières, le plus souvent en tant qu'intent sérialisé dans un champ extras, ou organisé en chaîne et analysé. Le contrôle partiel des paramètres peut également conduire au même résultat.

Impact

L'impact peut varier. Un pirate informatique peut exécuter une fonctionnalité interne dans l'application vulnérable ou accéder à des composants privés tels que des objets ContentProvider non exportés.

Stratégies d'atténuation

Général

En général, n'exposez pas les fonctionnalités liées à la redirection des intents imbriqués. Si cela est inévitable, appliquez les méthodes d'atténuation suivantes :

  • Nettoyez correctement les informations regroupées. Il est important de vérifier ou de supprimer les indicateurs (GRANT_URI_PERMISSIONS), et d'identifier où l'intent est redirigé. IntentSanitizer peut vous aider.
  • Utilisez des objets PendingIntent. Cela empêchera l'exportation du composant et rendra l'intent d'action cible immuable.

Les applications peuvent vérifier où un intent est redirigé à l'aide de méthodes telles que 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);
}

Les applications peuvent utiliser IntentSanitizer avec une logique semblable à celle-ci :

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

Erreurs courantes

  • Vérifier si getCallingActivity() renvoie une valeur non nulle. Les applications malveillantes peuvent fournir une valeur nulle pour cette fonction.
  • Supposer que checkCallingPermission() fonctionne dans tous les contextes ou que la méthode génère une exception lorsqu'elle renvoie un nombre entier.

Fonctionnalités de débogage

Pour les applications qui ciblent Android 12 (niveau d'API 31) ou une version ultérieure, vous pouvez activer une fonctionnalité de débogage qui, dans certains cas, permet de détecter si votre application effectue un lancement d'intent non sécurisé.

Si votre application effectue les deux actions suivantes, le système détecte un lancement d'intent non sécurisé, et une violation StrictMode se produit :

  • Votre application dissocie un intent imbriqué des extras d'un intent livré.
  • Votre application démarre immédiatement un composant d'application à l'aide de cet intent imbriqué, par exemple en transmettant l'intent dans startActivity(), startService() ou bindService().

Ressources

  • Remarque : Le texte du lien s'affiche lorsque JavaScript est désactivé
  • Intents en attente