Root Detection in mobiele apps — essentie, detectiemethoden en werkingsprincipe

Auteur: IT Sectr Gepubliceerd: 2026-04-03 Leestijd: 9 min

Root Detection — een beveiligingsmechanisme dat Android-apps beschermt tegen uitvoering op apparaten met superuser-privileges. Bank-, betalings- en bedrijfsapps blokkeren of beperken functionaliteit op geroote apparaten, omdat root-toegang de beperkingen van de Android-sandbox opheft en mogelijkheden opent voor het onderscheppen van verkeer, het lezen van procesgeheugen en het vervalsen van gegevens. Volgens OWASP Mobile Top 10 (2024) valt het ontbreken van Root Detection onder categorie M8 (Security Decisions via Untrusted Inputs). Root Detection is gebaseerd op een combinatie van statische controles van het bestandssysteem en dynamische analyse van runtime-gedrag.

Belangrijkste punten

  • Root Detection — controle van een Android-apparaat op root-toegang om de app te beschermen tegen uitvoering in een gecompromitteerde omgeving
  • Statische methoden controleren het bestandssysteem op de aanwezigheid van su-binary's, Superuser-apps en wijzigingen in systeempartities
  • Dynamische methoden analyseren de runtime: controle van Build.TAGS, poging tot openen van /proc/self/maps met bevoorrechte processen
  • Native implementatie in C/C++ via JNI biedt weerstand tegen omzeiling via Xposed en Frida op Java-niveau
  • Beveiliging Root Detection vereist continue obfuscatie en server-side verificatie om vervalsing van controle-resultaten te voorkomen

Wat is Root Detection?

Root Detection — een softwaremechanisme dat de aanwezigheid van root-toegang op een Android-apparaat bepaalt. Root-toegang biedt volledige controle over het besturingssysteem, waardoor apps en scripts opdrachten kunnen uitvoeren met UID 0. Op een geroot apparaat gaat de isolatie van apps (Android Sandbox) verloren, waardoor toetsenbordinvoer kan worden onderschept, SQLite-databases van andere apps kunnen worden gelezen, code in processen kan worden geïnjecteerd en SSL-certificaten in de vertrouwde opslag kunnen worden vervalst.

Voor financiële en bedrijfsapps vormt gebruik op een geroot apparaat een onaanvaardbaar risico: een aanvaller krijgt toegang tot tokens, sessiesleutels en persoonlijke gegevens. Regelgevende instanties, waaronder de PCI Security Standards Council, eisen van betalingsapps dat ze root-toegang detecteren en erop reageren. Als reactie hierop integreren Android-ontwikkelaars Root Detection als onderdeel van een proactieve beveiligingsstrategie.

Er zijn twee benaderingen voor detectie: statisch, waarbij het bestandssysteem en geïnstalleerde pakketten worden geanalyseerd, en dynamisch, waarbij controles in runtime worden uitgevoerd. De gecombineerde aanpak wordt als het meest betrouwbaar beschouwd, omdat deze verschillende omzeilingsvectoren dekt. Volgens onderzoek van NowSecure (2025) bevat 76% van de bankapps in de top 100 van Google Play een vorm van Root Detection.

Statische methoden voor rootdetectie

Statische methoden worden uitgevoerd bij het opstarten van de app en controleren op tekenen van root-toegang die door root-tools in het bestandssysteem zijn achtergelaten. Deze methoden vereisen geen uitvoering van bevoorrechte opdrachten en werken in de context van een gewone app.

Controleren op aanwezigheid van su-binary

Het belangrijkste teken van root-toegang — de aanwezigheid van het uitvoerbare bestand su op standaardpaden: /system/bin/su, /system/xbin/su, /sbin/su, /su/bin/su. De app controleert het bestaan van het bestand via File.exists() of een native implementatie van access() uit libc. Aanvullend kan men proberen su --version of su -c id uit te voeren en de exit-code te controleren.

Zoeken naar root-managers

Typische apps voor het beheren van root-toegang: Superuser, SuperSU, Magisk Manager, KingRoot. Hun aanwezigheid wordt gecontroleerd via PackageManager.getPackageInfo() of het lezen van de /data/app/-directory. Te controleren pakketten: com.topjohnwu.magisk, eu.chainfire.supersu, com.noshufou.android.su, com.thirdparty.superuser, com.koushikdutta.superuser, com.zacharee1.systemuituner.

Controleren van systeemeigenschappen

Android slaat informatie over de systeemstatus op in systeemeigenschappen die toegankelijk zijn via System.getProperty en Build.TAGS. Als Build.TAGS test-keys bevat in plaats van release-keys — duidt dit op aangepaste firmware, vaak met root-toegang. Aanvullend worden ro.build.tags, ro.debuggable en ro.secure gecontroleerd door /system/build.prop te lezen.

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) {
                // pakket niet gevonden
            }
        }
        return false;
    }
}

Dynamische controlemethoden

Dynamische methoden worden uitgevoerd tijdens de werking van de app en analyseren de uitvoeringsomgeving. In tegenstelling tot statische methoden kunnen ze root detecteren die verborgen is via Magisk Hide of Zygisk, omdat ze het gedrag van het systeem controleren, niet alleen de bestandsstructuur.

Controleren van mountpunten

Bij root-toegang worden sommige systeempartities gemount met de vlag rw (read-write) in plaats van ro (read-only). De app leest /proc/mounts en controleert of /system is gemount als ro. Als /system is gemount als rw — is dit een teken van een gemodificeerd systeem. Aanvullend wordt de aanwezigheid van /su-mounting via Magisk gecontroleerd.

Test van de veilige modus

Android Safe Mode schakelt apps van derden uit, inclusief root-managers. Een correcte implementatie van Root Detection kan controleren of het apparaat in de veilige modus werkt. Als de app detecteert dat root-managers niet zichtbaar zijn, maar de su-binary wel bestaat — is dit een teken van Magisk Hide.

Controleren van opdrachtuitvoering

Poging om su -c id uit te voeren via ProcessBuilder of Runtime.exec — een directe test van root-toegang. Magisk kan deze aanroep echter onderscheppen. Een betrouwbaardere optie — controle via native code: openen van /proc/1/limits of /proc/self/maps en analyse van de UID van lopende processen. Als de app UID 0 kan krijgen of bestanden kan lezen die alleen toegankelijk zijn voor root — is het apparaat gecompromitteerd.

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

    // Controle van /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) {
        // fout bij lezen van mount
    }

    return false;
}

Native implementatie van Root Detection in C++

Root Detection geïmplementeerd in Java wordt gemakkelijk omzeild via Xposed-modules of Frida, die Java-methoden onderscheppen en retourwaarden vervalsen. Native implementatie in C++ via JNI is aanzienlijk robuuster: dynamische analysetools die op Java-niveau werken, zien de native libc-aanroepen zoals stat, access, popen en dlopen niet.

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

Native controle gebruikt geen Java API, waardoor het onzichtbaar is voor omzeilingstools die op Dalvik/ART-niveau werken. Voor extra beveiliging wordt aanbevolen constanten (lijst van paden) niet in de read-only-sectie op te slaan, maar ze te berekenen via eenvoudige omkeerbare functies. Stat-aanroep uit libc richt zich direct tot de Linux-kernel, omzeilt Java-wrappers en kan niet worden onderschept via Xposed.

Methoden om Root Detection te omzeilen

Beveiligingsontwikkelaars moeten de bestaande omzeilingsmethoden begrijpen om een robuust detectiesysteem te bouwen. Elke omzeilingsmethode vereist een tegenmaatregel op het juiste niveau.

Omzeilen via Magisk Hide en Zygisk

Magisk — de populairste root-tool op Android 9–14. Magisk Hide verbergt de aanwezigheid van su uit /proc en vervalst de resultaten van padcontroles. Magisk werkt op kernelniveau en onderschept stat() en access() voordat de app ze ziet. Tegenmaatregel: controle op de aanwezigheid van Magisk zelf via /sbin/.magisk of controle door het lezen van eigen maps — Magisk injecteert zijn bibliotheek in elk proces.

Omzeilen via Frida

Frida — een dynamisch instrumentatieprogramma dat native functies kan onderscheppen via Ptrace of Dobby. Frida vervangt de retourwaarde van elke controle door het resultaat van stat te vervalsen naar ENOENT. Tegenmaatregel: controle van de integriteit van native functies door het berekenen van een checksum van instructies in het geheugen en detectie van Frida via analyse van /proc/self/maps op aanwezigheid van frida-agent.so of frida-helper.

Omzeilen via APK-patch

Root Detection geïmplementeerd in Java wordt in 2–3 minuten verwijderd: APK wordt uitgepakt met apktool, in smali-code wordt de retourwaarde van de methode gewijzigd naar false, APK wordt opnieuw samengesteld en ondertekend. Tegenmaatregel: verplaatsen van kritische logica naar native code en controle van de digitale handtekening van de app in runtime via Signature API of vergelijking van de APK-hash met de referentie op de server.

Aanbevelingen voor betrouwbare beveiliging

Effectieve Root Detection is gebaseerd op een gelaagde architectuur. Geen enkele methode afzonderlijk biedt voldoende beveiliging. Een combinatie van statische en dynamische controles, native code en serververificatie geeft maximale robuustheid.

Serververificatie

Vertrouw niet alleen op client-side controle. Stuur de resultaten van Root Detection samen met een eenmalig sessietoken naar de server. De server neemt de beslissing over blokkering of beperking van functionaliteit. Dit voorkomt aanvallen op API-niveau, waar de client-app kan worden gemodificeerd, maar de server de vertrouwde partij blijft.

Obfuscatie van controlecodes

De Root Detection-code moet worden geobfusceerd. Als een aanvaller in jadx een duidelijke reeks controles van su-paden ziet — duurt omzeiling minuten. Gebruik ProGuard of DexGuard om de controlestroom te verwarren en strings te versleutelen. Obfuscatie verhoogt de analysetijd van beveiligingscode van enkele minuten naar enkele uren.

Regelmatige update van handtekeningen

De lijst met te controleren paden, pakketten en indicatoren moet met elke release van de app worden bijgewerkt. Nieuwe root- en omzeilingstools verschijnen maandelijks. Een statische lijst die een jaar niet is gewijzigd, detecteert moderne methoden niet. Het wordt aanbevolen om actuele handtekeningen van de server te laden bij het opstarten van de app voordat controles worden uitgevoerd.

Veelgestelde vragen

Waarom hebben apps Root Detection nodig?

Root Detection beschermt tegen het uitvoeren van de app op een apparaat waar de Android-sandbox is uitgeschakeld. Op een geroot apparaat kan elke app gegevens van andere apps lezen. Bankapps en betalingsapps zijn verplicht om werking op geroote apparaten te blokkeren volgens de vereisten van PCI DSS en aanbevelingen van OWASP Mobile Security.

Hoe werkt Magisk Hide?

Magisk Hide gebruikt het mechanisme van mount namespace. Voor elk proces dat in de uitzonderingslijst staat, creëert Magisk een geïsoleerde namespace waarin de su-binary onzichtbaar is. Systeemaanroepen stat, access en open zien in deze namespace de Magisk-bestanden niet. Magisk kan worden gedetecteerd door de aanwezigheid van /proc/self/maps te controleren en te zoeken naar magisk-dump.

Kan Root Detection worden omzeild zonder root?

Ja, als de app de integriteit van zijn eigen code niet controleert. Via Frida kan men de Java-controlemethode onderscheppen en geforceerd false laten retourneren. Tegenmaatregel — native implementatie van kritische logica in C++ en integriteitscontrole via hash van het DEX-bestand. Zonder obfuscatie wordt elke Root Detection in Java in 5–10 minuten omzeild.

Wat zijn safety net en attestation?

SafetyNet (verouderd) en Play Integrity API — dit zijn servercontroles van Google die de integriteit van het apparaat bevestigen. Ze omvatten controle van de bootloader, systeemhandtekening en root-status. Play Integrity API — de aanbevolen vervanging voor SafetyNet, die drie niveaus biedt: BASIC, DEVICE en STRONG. Root Detection op de client vult serverattestatie aan.

Hoe test ik Root Detection in mijn eigen app?

Installeer de app op een echt geroot apparaat (bijv. Pixel met Magisk). Controleer of de blokkering wordt geactiveerd. Probeer vervolgens root te verbergen via Magisk Hide voor uw app en herhaal de test. Gebruik voor een grondige controle Frida om doelmethoden te onderscheppen en zorg ervoor dat de native beveiliging niet kan worden omzeild.

Samenvatting

  • Root Detection — een verplichte beveiligingscomponent voor bank-, betalings- en bedrijfsapps op Android, die werkt op een combinatie van statische en dynamische controles
  • Statische methoden omvatten het zoeken naar de su-binary op standaardpaden, controle van geïnstalleerde root-managers en analyse van systeemeigenschappen Build.TAGS
  • Dynamische methoden analyseren het mounten van /system in rw-modus, controleren de integriteit van /proc/mounts en voeren tests uit voor het uitvoeren van bevoorrechte opdrachten
  • Native implementatie in C++ via JNI maakt controles onzichtbaar voor Xposed en Frida die op Java-niveau werken en vereist omzeiling via Dobby of Ptrace
  • Magisk Hide — de belangrijkste tool voor het omzeilen van Root Detection via mount namespaces, gedetecteerd via analyse van /proc/self/maps op aanwezigheid van magisk-bibliotheken
  • Aanbevolen architectuur: native controles + code-obfuscatie + serververificatie van resultaten + regelmatige update van handtekeningen
  • Play Integrity API van Google vult client-side Root Detection aan met serverattestatie van het apparaat, wat zorgt voor een uitgebreide beveiliging

We ontwikkelen een mobiele applicatie turnkey

IT Sectr creëert sinds 2017 iOS- en Android-applicaties voor startups en bedrijven. We adviseren u en stellen de beste oplossing voor.

Bespreek het project

Lees ook