Oparta na uprawnieniach kontrola dostępu do wyeksportowanych komponentów

Kategoria OWASP: MASVS-PLATFORM: Platform Interaction

Omówienie

Uprawnienie na Androidzie to identyfikator ciągu znaków zadeklarowany w manifeście aplikacji w celu żądania dostępu do ograniczonych danych lub działań, wymuszonego w czasie wykonywania przez framework Androida.

Poziomy uprawnień Androida wskazują na potencjalne ryzyko związane z uprawnieniami:

  • Normalne: uprawnienia niskiego ryzyka, przyznawane automatycznie podczas instalacji.
  • Niebezpieczne: uprawnienia wysokiego ryzyka, które mogą umożliwiać dostęp do wrażliwych danych użytkownika. Wymagają one wyraźnej zgody użytkownika w czasie działania aplikacji.
  • Podpis: przyznawane tylko aplikacjom podpisanym tym samym certyfikatem co aplikacja deklarująca uprawnienie. Zwykle używane w przypadku aplikacji systemowych lub interakcji między aplikacjami tego samego dewelopera.

Wrażliwości związane z kontrolą dostępu na podstawie uprawnień występują, gdy komponent aplikacji (taki jak aktywność, odbiorca, dostawca treści lub usługa) spełnia wszystkie te kryteria:

  • komponent nie jest powiązany z żadnym android:permission w Manifest;
  • Komponent wykonuje czynność poufną, dla której istnieją uprawnienia już zatwierdzone przez użytkownika.
  • Komponent jest eksportowany;
  • Komponent nie wykonuje ręcznych kontroli uprawnień (na poziomie pliku manifestu ani kodu).

W takim przypadku złośliwa aplikacja może wykonywać działania związane z danymi newralgicznymi, wykorzystując uprawnienia podatnego na ataki komponentu, a następnie przekazując uprawnienia podatnej na ataki aplikacji złośliwej aplikacji.

Wpływ

Eksportowanie podatnych komponentów może służyć do uzyskiwania dostępu do zasobów poufnych lub wykonywania czynności związanych z danymi poufnymi. Skutki tego niepożądanego zachowania zależą od kontekstu podatnego na atak komponentu i jego uprawnień.

Łagodzenie

Wymagaj uprawnień do zadań związanych z danymi poufnymi

Podczas eksportowania komponentu z uprawnieniami dostępu do danych wrażliwych wymagaj tych samych uprawnień dla wszystkich przychodzących żądań. W środowisku Android Studio IDE można przeprowadzić kontrolę lintowania odbiorników i usług, aby wykryć tę lukę w zabezpieczeniach i zalecić uzyskanie odpowiednich uprawnień.

Programiści mogą wymagać uprawnień do przychodzących żądań, deklarując je w pliku Manifest lub na poziomie kodu podczas implementacji usługi, jak w przypadku tych przykładów.

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

    }
}

Nie eksportuj komponentu

Unikaj eksportowania komponentów z dostępem do zasobów poufnych, jeśli nie jest to absolutnie konieczne. Aby to zrobić, ustaw wartość android:exported w pliku Manifest na false. Od poziomu interfejsu API 31 w górę ten atrybut jest domyślnie ustawiony na false.

XML

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

Stosowanie uprawnień opartych na podpisach

Udostępniając dane 2 aplikacjom, które są pod Twoją kontrolą lub należą do Ciebie, używaj uprawnień opartych na sygnaturze. Te uprawnienia nie wymagają potwierdzenia przez użytkownika. Zamiast tego sprawdzają, czy aplikacje uzyskujące dostęp do danych są podpisane tym samym kluczem podpisywania. Takie rozwiązanie zapewnia większą wygodę i bezpieczeństwo użytkowników. Jeśli deklarujesz uprawnienia niestandardowe, zapoznaj się z odpowiednimi wskazówkami dotyczącymi bezpieczeństwa.

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" />

Punkty końcowe pojedynczego zadania

Zaimplementuj aplikację zgodnie z zasadą oddzielania funkcji. Każdy punkt końcowy powinien wykonywać tylko niewielki zestaw konkretnych zadań z określonymi uprawnieniami. Ta sprawdzona metoda projektowania pozwala też deweloperowi stosować szczegółowe uprawnienia do każdego punktu końcowego. Nie należy na przykład tworzyć pojedynczego punktu końcowego, który obsługuje zarówno kalendarz, jak i kontakty.

Materiały