Root Detection dans les applications mobiles — méthodes de détection et principe de fonctionnement

Auteur : IT Sectr Publié le : 2026-04-03 Temps de lecture : 9 min

Root Detection est un mécanisme de sécurité qui protège les applications Android contre l'exécution sur des dispositifs disposant de privilèges de superutilisateur. Les applications bancaires, de paiement et d'entreprise bloquent ou restreignent les fonctionnalités sur les appareils rootés, car l'accès root supprime les restrictions du sandbox Android et ouvre la possibilité d'intercepter le trafic, de lire la mémoire des processus et de falsifier les données. Selon OWASP Mobile Top 10 (2024), l'absence de Root Detection relève de la catégorie M8 (Security Decisions via Untrusted Inputs). Root Detection repose sur une combinaison de vérifications statiques du système de fichiers et d'analyse dynamique du comportement d'exécution.

Points clés

  • Root Detection — vérification d'un appareil Android pour détecter l'accès root et protéger l'application contre l'exécution dans un environnement compromis
  • Méthodes statiques vérifient le système de fichiers pour les binaires su, les applications Superuser et les modifications des partitions système
  • Méthodes dynamiques analysent l'exécution : vérification de Build.TAGS, tentative d'ouverture de /proc/self/maps avec des processus privilégiés
  • Implémentation native en C/C++ via JNI offre une résistance au contournement via Xposed et Frida au niveau Java
  • Sécurité Root Detection nécessite une obscurcissement continu et une vérification côté serveur pour empêcher la falsification des résultats

Qu'est-ce que Root Detection ?

Root Detection est un mécanisme logiciel qui détecte la présence d'un accès root sur un appareil Android. L'accès root fournit un contrôle total sur le système d'exploitation, permettant aux applications et scripts d'exécuter des commandes avec UID 0. Sur un appareil rooté, l'isolation des applications (Android Sandbox) est perdue, rendant possible l'interception des saisies clavier, la lecture des bases de données SQLite d'autres applications, l'injection de code dans les processus et le remplacement des certificats SSL dans le stockage de confiance.

Pour les applications financières et d'entreprise, fonctionner sur un appareil rooté présente un risque inacceptable : un attaquant obtient l'accès aux tokens, aux clés de session et aux données personnelles. Les régulateurs, dont le PCI Security Standards Council, exigent que les applications de paiement détectent et répondent à l'accès root. En réponse, les développeurs Android intègrent Root Detection dans le cadre d'une stratégie de protection proactive.

Il existe deux approches de détection : statique, qui analyse le système de fichiers et les paquets installés, et dynamique, qui effectue des vérifications à l'exécution. L'approche combinée est considérée comme la plus fiable, car elle couvre différents vecteurs de contournement. Selon une étude de NowSecure (2025), 76 % des applications bancaires dans le top 100 du Google Play contiennent une forme de Root Detection.

Méthodes statiques de détection de root

Les méthodes statiques s'exécutent au démarrage de l'application et vérifient les signes d'accès root laissés par les outils de root dans le système de fichiers. Ces méthodes ne nécessitent pas l'exécution de commandes privilégiées et fonctionnent dans le contexte d'une application normale.

Vérification de l'existence du binaire su

Le principal indicateur d'accès root est la présence du fichier exécutable su dans les chemins standard : /system/bin/su, /system/xbin/su, /sbin/su, /su/bin/su. L'application vérifie l'existence du fichier via File.exists() ou une implémentation native de access() de libc. De plus, on peut tenter d'exécuter su --version ou su -c id et vérifier le code de sortie.

Recherche de gestionnaires root

Applications typiques pour gérer l'accès root : Superuser, SuperSU, Magisk Manager, KingRoot. Leur présence est vérifiée via PackageManager.getPackageInfo() ou en lisant le répertoire /data/app/. Paquets à vérifier : com.topjohnwu.magisk, eu.chainfire.supersu, com.noshufou.android.su, com.thirdparty.superuser, com.koushikdutta.superuser, com.zacharee1.systemuituner.

Vérification des propriétés système

Android stocke les informations d'état du système dans des propriétés système, accessibles via System.getProperty et Build.TAGS. Si Build.TAGS contient test-keys au lieu de release-keys, cela indique un firmware personnalisé, souvent avec accès root. De plus, ro.build.tags, ro.debuggable et ro.secure sont vérifiés en lisant /system/build.prop.

java
public class RootDetectionChecker {
    private static final String[] SU_PATHS = {
        "/system/bin/su",
        "/system/xbin/su",
        "/sbin/su",
        "/su/bin/su",
        "/system/sd/xbin/su"
    };

    public boolean checkRootByFiles() {
        for (String path : SU_PATHS) {
            if (new File(path).exists()) {
                return true;
            }
        }
        return false;
    }

    public boolean checkRootByPackages(Context ctx) {
        String[] packages = {
            "com.topjohnwu.magisk",
            "eu.chainfire.supersu",
            "com.noshufou.android.su",
            "com.koushikdutta.superuser"
        };
        for (String pkg : packages) {
            try {
                ctx.getPackageManager().getPackageInfo(pkg, 0);
                return true;
            } catch (PackageManager.NameNotFoundException e) {
                // package not found
            }
        }
        return false;
    }
}

Méthodes dynamiques de vérification

Les méthodes dynamiques s'exécutent pendant le fonctionnement de l'application et analysent l'environnement d'exécution. Contrairement aux méthodes statiques, elles peuvent détecter le root caché via Magisk Hide ou Zygisk, car elles vérifient le comportement du système et pas seulement la structure des fichiers.

Vérification des points de montage

Avec l'accès root, certaines partitions système sont montées avec le drapeau rw (lecture-écriture) au lieu de ro (lecture seule). L'application lit /proc/mounts et vérifie que /system est monté en ro. Si /system est monté en rw, cela indique un système modifié. De plus, la présence du montage /su via Magisk est vérifiée.

Test du mode sans échec

Le mode sans échec d'Android désactive les applications tierces, y compris les gestionnaires root. Une implémentation correcte de Root Detection peut vérifier si l'appareil fonctionne en mode sans échec. Si l'application détecte que les gestionnaires root ne sont pas visibles mais que le binaire su existe, c'est un indicateur de Magisk Hide.

Vérification d'exécution de commandes

Tenter d'exécuter su -c id via ProcessBuilder ou Runtime.exec est un test direct d'accès root. Cependant, Magisk peut intercepter cet appel. Une approche plus fiable est la vérification via du code natif : ouvrir /proc/1/limits ou /proc/self/maps et analyser l'UID des processus en cours. Si l'application peut obtenir UID 0 ou lire des fichiers accessibles uniquement à root, l'appareil est compromis.

java
public boolean checkRootDynamically() {
    // Build flags check
    String buildTags = Build.TAGS;
    if (buildTags != null && buildTags.contains("test-keys")) {
        return true;
    }

    // Checking /system mount
    try {
        BufferedReader reader = new BufferedReader(
            new InputStreamReader(new FileInputStream("/proc/mounts"))
        );
        String line;
        while ((line = reader.readLine()) != null) {
            if (line.contains("/system")
                && line.contains("rw")) {
                reader.close();
                return true;
            }
        }
        reader.close();
    } catch (IOException e) {
        // error reading mounts
    }

    return false;
}

Implémentation native de Root Detection en C++

Root Detection implémenté en Java est facilement contourné via les modules Xposed ou Frida, qui interceptent les méthodes Java et remplacent les valeurs de retour. L'implémentation native en C++ via JNI est considérablement plus résistante : les outils d'analyse dynamique opérant au niveau Java ne voient pas les appels natifs de libc tels que stat, access, popen et dlopen.

cpp
#include <unistd.h>
#include <sys/stat.h>
#include <cstring>
#include <vector>

extern "C"
JNIEXPORT jboolean JNICALL
Java_com_example_checker_RootCheck_nativeCheck(
    JNIEnv* env, jobject instance) {

    std::vector<const char*> paths = {
        "/system/bin/su",
        "/system/xbin/su",
        "/sbin/su",
        "/data/local/su"
    };

    struct stat st;
    for (const char* path : paths) {
        if (stat(path, &st) == 0) {
            return JNI_TRUE;
        }
    }
    return JNI_FALSE;
}

La vérification native n'utilise pas l'API Java, ce qui la rend invisible pour les outils de contournement opérant au niveau Dalvik/ART. Pour une protection supplémentaire, il est recommandé de ne pas stocker les constantes (liste de chemins) dans une section en lecture seule, mais de les calculer via des fonctions réversibles simples. L'appel stat de libc accède directement au noyau Linux, contournant les wrappers Java, et ne peut pas être intercepté via Xposed.

Méthodes de contournement de Root Detection

Les développeurs de protection doivent comprendre les méthodes de contournement existantes pour construire un système de détection robuste. Chaque méthode de contournement nécessite une contre-mesure au niveau approprié.

Contournement via Magisk Hide et Zygisk

Magisk est l'outil de root le plus populaire sur Android 9–14. Magisk Hide cache la présence de su de /proc et falsifie les résultats de vérification des chemins. Magisk opère au niveau du noyau et intercepte stat() et access() avant que l'application ne les voie. Contre-mesure : vérifier la présence de Magisk lui-même via l'existence de /sbin/.magisk ou vérifier via la lecture des propres maps de l'application — Magisk injecte sa bibliothèque dans chaque processus.

Contournement via Frida

Frida est un outil d'instrumentation dynamique qui peut intercepter les fonctions natives via Ptrace ou Dobby. Frida remplace la valeur de retour de toute vérification, falsifiant le résultat de stat en ENOENT. Contre-mesure : vérifier l'intégrité des fonctions natives en calculant une somme de contrôle des instructions en mémoire et détecter Frida via l'analyse de /proc/self/maps pour la présence de frida-agent.so ou frida-helper.

Contournement via patch de l'APK

Root Detection implémenté en Java est supprimé en 2–3 minutes : l'APK est décompilé via apktool, la valeur de retour de la méthode est changée en false dans le code smali, l'APK est reconstruit et signé. Contre-mesure : transférer la logique critique dans le code natif et vérifier la signature numérique de l'application à l'exécution via l'API de Signature ou comparer le hash de l'APK avec une référence sur le serveur.

Recommandations pour une protection fiable

Un Root Detection efficace repose sur une architecture multicouche. Aucune méthode unique ne fournit une protection suffisante à elle seule. La combinaison de vérifications statiques et dynamiques, de code natif et de vérification côté serveur offre une résistance maximale.

Vérification côté serveur

Ne vous fiez pas uniquement à la vérification côté client. Envoyez les résultats de Root Detection au serveur avec un token de session à usage unique. Le serveur décide de bloquer ou de restreindre les fonctionnalités. Cela empêche les attaques au niveau de l'API, où l'application cliente peut être modifiée tandis que le serveur reste une partie de confiance.

Obscurcissement du code

Le code de Root Detection doit être obscurci. Si un attaquant voit une séquence claire de vérifications de chemins su dans jadx, le contournement prendra quelques minutes. Utilisez ProGuard ou DexGuard pour obscurcir le flux de contrôle et chiffrer les chaînes. L'obscurcissement augmente le temps d'analyse du code de protection de quelques minutes à plusieurs heures.

Mise à jour régulière des signatures

La liste des chemins, paquets et indicateurs vérifiés doit être mise à jour à chaque version de l'application. De nouveaux outils de root et de contournement apparaissent chaque mois. Une liste statique qui n'a pas changé depuis un an ne détectera pas les méthodes modernes. Il est recommandé de charger les signatures actuelles depuis le serveur au démarrage de l'application avant d'effectuer les vérifications.

Foire aux questions

Pourquoi les applications ont-elles besoin de Root Detection ?

Root Detection protège contre l'exécution d'une application sur un appareil où le sandbox Android est désactivé. Sur un appareil rooté, toute application peut lire les données d'autres applications. Les applications bancaires et de paiement sont tenues de bloquer le fonctionnement sur les appareils rootés conformément aux exigences PCI DSS et aux recommandations OWASP Mobile Security.

Comment fonctionne Magisk Hide ?

Magisk Hide utilise un mécanisme d'espace de noms de montage (mount namespace). Pour chaque processus dans la liste d'exclusion, Magisk crée un espace de noms isolé où le binaire su est invisible. Les appels système stat, access et open dans cet espace de noms ne voient pas les fichiers Magisk. Magisk peut être détecté en vérifiant la présence de /proc/self/maps et en recherchant les dumps magisk.

Peut-on contourner Root Detection sans root ?

Oui, si l'application ne vérifie pas l'intégrité de son code. Via Frida, on peut intercepter la méthode Java de vérification et la forcer à retourner false. La contre-mesure est une implémentation native de la logique critique en C++ et une vérification d'intégrité via le hash du fichier DEX. Sans obscurcissement, tout Root Detection en Java est contourné en 5–10 minutes.

Qu'est-ce que SafetyNet et l'attestation ?

SafetyNet (obsolète) et Play Integrity API sont des vérifications côté serveur de Google qui confirment l'intégrité de l'appareil. Elles incluent la vérification du bootloader, de la signature système et du statut root. Play Integrity API est le remplacement recommandé de SafetyNet, offrant trois niveaux : BASIC, DEVICE et STRONG. Root Detection côté client complète l'attestation côté serveur.

Comment tester Root Detection dans votre application ?

Installez l'application sur un véritable appareil rooté (par exemple, un Pixel avec Magisk). Vérifiez si le blocage se déclenche. Essayez ensuite de cacher le root via Magisk Hide pour votre application et relancez le test. Pour un test approfondi, utilisez Frida pour intercepter les méthodes cibles et assurez-vous que la protection native ne peut pas être contournée.

Résumé

  • Root Detection est un composant de sécurité obligatoire pour les applications Android bancaires, de paiement et d'entreprise, fonctionnant sur une combinaison de vérifications statiques et dynamiques
  • Méthodes statiques incluent la recherche du binaire su dans les chemins standard, la vérification des gestionnaires root installés et l'analyse des propriétés système Build.TAGS
  • Méthodes dynamiques analysent le montage de /system en mode rw, vérifient l'intégrité de /proc/mounts et effectuent des tests d'exécution de commandes privilégiées
  • Implémentation native en C++ via JNI rend les vérifications invisibles pour Xposed et Frida opérant au niveau Java, nécessitant un contournement via Dobby ou Ptrace
  • Magisk Hide est l'outil principal de contournement de Root Detection via les espaces de noms de montage, détectable par l'analyse de /proc/self/maps pour les bibliothèques magisk
  • Architecture recommandée : vérifications natives + obscurcissement du code + vérification des résultats côté serveur + mise à jour régulière des signatures
  • Play Integrity API de Google complète Root Detection côté client avec l'attestation d'appareil côté serveur, offrant une protection complète

Nous développerons une application mobile clé en main

IT Sectr crée des applications iOS et Android pour les startups et les entreprises depuis 2017. Nous vous conseillerons et vous proposerons la meilleure solution.

Discuter du projet

Lisez aussi