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

Kategoria OWASP: MASVS-PLATFORM: Platform Interaction

Omówienie

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

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

  • Normalne: uprawnienia o niskim ryzyku, które są automatycznie przyznawane w momencie 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: przyznawany tylko aplikacjom podpisanym tym samym certyfikatem co aplikacja deklarująca uprawnienie. Zwykle używany w przypadku aplikacji systemowych lub interakcji między aplikacjami tego samego dewelopera.

W przypadku kontroli dostępu na podstawie uprawnień występują luki związane z komponentami aplikacji (takich jak aktywność, odbiorca, dostawca treści lub usługa), które spełniają wszystkie te kryteria:

  • komponent nie jest powiązany z żadnym android:permission w Manifest;
  • komponent wykonuje zadanie związane z danymi wrażliwymi, do których dostęp wymaga uprawnienia, które użytkownik już zatwierdził;
  • Komponent jest eksportowany;
  • komponent nie wykonuje żadnych ręcznych kontroli uprawnień (na poziomie pliku manifestu lub 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 działań związanych z danymi poufnymi. Skutki tego niepożądanego zachowania zależą od kontekstu podatnego na atak komponentu i jego uprawnień.

Środki zaradcze

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ń. IDE Android Studio zawiera mechanizmy kontroli lint dla odbiorcówusług, które wykrywają tę lukę w zabezpieczeniach i zalecają wymaganie 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 przykładów poniżej.

XmlKotlinJava
<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>
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
   
}
}
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, chyba że 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ń na podstawie podpisu

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, a 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

Wdrożyć aplikację zgodnie z zasadą oddzielania funkcji. Każdy punkt końcowy powinien wykonywać tylko pewien zestaw określonych zadań z określonymi uprawnieniami. Ta dobra praktyka projektowania umożliwia też deweloperowi stosowanie szczegółowych uprawnień do poszczególnych punktów końcowych. Nie należy na przykład tworzyć pojedynczego punktu końcowego, który obsługuje zarówno kalendarz, jak i kontakty.

Materiały