Berechtigungsbasierte Zugriffssteuerung auf exportierte Komponenten

OWASP-Kategorie:MASVS-PLATFORM: Platform Interaction

Übersicht

Eine Android-Berechtigung ist ein String-Identifier, der im Manifest der App deklariert wird, um Zugriff auf eingeschränkte Daten oder Aktionen anzufordern. Sie wird zur Laufzeit vom Android-Framework erzwungen.

Android-Berechtigungsstufen geben das potenzielle Risiko an, das mit der Berechtigung verbunden ist:

  • Normal: Berechtigungen mit geringem Risiko, die bei der Installation automatisch gewährt werden
  • Gefährlich: Berechtigungen mit hohem Risiko, die Zugriff auf vertrauliche Nutzerdaten ermöglichen und bei der Ausführung eine ausdrückliche Nutzergenehmigung erfordern
  • Signatur: Wird nur Apps gewährt, die mit demselben Zertifikat wie die App signiert sind, die die Berechtigung deklariert. Wird in der Regel für System-Apps oder Interaktionen zwischen Apps desselben Entwicklers verwendet.

Sicherheitslücken im Zusammenhang mit berechtigungsbasierten Zugriffssteuerungen treten auf, wenn eine Komponente einer App (z. B. activity, receiver, content provider oder service) alle folgenden Kriterien erfüllt:

  • Die Komponente ist keiner android:permission in der Manifest zugeordnet.
  • Die Komponente führt eine sensible Aufgabe aus, für die eine Berechtigung vorhanden ist, die der Nutzer bereits genehmigt hat.
  • Die Komponente wird exportiert.
  • Die Komponente führt keine manuellen Berechtigungsprüfungen (auf Manifest- oder Codeebene) durch.

In diesem Fall kann eine schädliche App vertrauliche Aktionen ausführen, indem sie die Berechtigungen der anfälligen Komponente missbraucht und die Berechtigungen der anfälligen App an die schädliche App weiterleitet.

Auswirkungen

Durch den Export anfälliger Komponenten kann auf sensible Ressourcen zugegriffen oder sensible Aktionen ausgeführt werden. Die Auswirkungen dieses unerwünschten Verhaltens hängen vom Kontext der anfälligen Komponente und ihren Berechtigungen ab.

Gegenmaßnahmen

Berechtigungen für vertrauliche Aufgaben erforderlich machen

Wenn Sie eine Komponente mit vertraulichen Berechtigungen exportieren, müssen Sie für jede eingehende Anfrage dieselben Berechtigungen anfordern. Die Android Studio-IDE bietet Lint-Prüfungen für Receiver und Dienste, um diese Sicherheitslücke zu erkennen und die erforderlichen Berechtigungen zu empfehlen.

Entwickler können Berechtigungen für eingehende Anfragen entweder durch Deklarieren in der Datei Manifest oder auf Codeebene bei der Implementierung des Dienstes anfordern, wie in den folgenden Beispielen.

XML

<manifest ...>
    <uses-permission android:name="android.permission.READ_CONTACTS" />

    <application ...>
        <service android:name=".MyExportService"
                 android:exported="true"
                 android:permission="android.permission.READ_CONTACTS" />

        </application>
</manifest>

Kotlin

class MyExportService : Service() {

    private val binder = MyExportBinder()

    override fun onBind(intent: Intent): IBinder? {
        // Enforce calling app has the required permission
        enforceCallingPermission(Manifest.permission.READ_CONTACTS, "Calling app doesn't have READ_CONTACTS permission.")
        // Permission is enforced, proceed with export logic
        return binder
    }

    // Inner class for your Binder implementation
    private inner class MyExportBinder : Binder() {
        // Permission is enforced, proceed with export logic
    }
}

Java

public class MyExportService extends Service {

    @Override
    public IBinder onBind(Intent intent) {
        // Enforce calling app has the required permission
        enforceCallingPermission(Manifest.permission.READ_CONTACTS, "Calling app doesn't have READ_CONTACTS permission.");

        return binder;

    }

    // Inner class for your Binder implementation
    private class MyExportBinder extends Binder {
        // Permission is enforced, proceed with export logic

    }
}

Komponente nicht exportieren

Vermeiden Sie den Export von Komponenten mit Zugriff auf vertrauliche Ressourcen, es sei denn, dies ist unbedingt erforderlich. Dazu müssen Sie android:exported in der Datei Manifest für Ihre Komponente auf false festlegen. Ab API-Level 31 ist dieses Attribut standardmäßig auf false festgelegt.

XML

<activity
    android:name=".MyActivity"
    android:exported="false"/>

Signaturbasierte Berechtigungen anwenden

Wenn Sie Daten zwischen zwei Apps teilen, die Sie kontrollieren oder die Ihre eigenen sind, verwenden Sie signaturbasierte Berechtigungen. Für diese Berechtigungen ist keine Nutzerbestätigung erforderlich. Stattdessen wird geprüft, ob die Apps, die auf die Daten zugreifen, mit demselben Signaturschlüssel signiert sind. Diese Einrichtung bietet eine optimierte und sichere Nutzererfahrung. Wenn Sie benutzerdefinierte Berechtigungen deklarieren, müssen Sie die entsprechenden Sicherheitsrichtlinien beachten.

XML

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.myapp">
    <permission android:name="my_custom_permission_name"
                android:protectionLevel="signature" />

Endpunkte für einzelne Aufgaben

Implementieren Sie Ihre App gemäß dem Designprinzip Separation of Concerns. Jeder Endpunkt sollte nur eine kleine Anzahl spezifischer Aufgaben mit bestimmten Berechtigungen ausführen. Diese gute Designpraxis ermöglicht es dem Entwickler auch, für jeden Endpunkt detaillierte Berechtigungen festzulegen. Vermeiden Sie beispielsweise, einen einzelnen Endpunkt zu erstellen, der sowohl Kalender als auch Kontakte bereitstellt.

Ressourcen