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
wManifest
; - 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ów i usł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.
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, 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
- Android Access to app protected components from the Oversecured blog
- Sprawdzone metody dla dostawców treści
- Uprawnienia czasu działania (niebezpieczne)
- Zasada projektowania polegająca na rozdzielaniu problemów
- Dokumentacja dotycząca uprawnień na Androidzie
- Wskazówki dotyczące bezpieczeństwa odbiorników transmisji na Androidzie
- Wskazówki dotyczące bezpieczeństwa usług na Androidzie
- Android 12 (poziom 31 interfejsu API) – wartość domyślna eksportowana jako „false”
- Sprawdzanie Lint: nie należy eksportować klasy PreferenceActivity
- Sprawdzanie błędów: eksportowany odbiorca nie wymaga uprawnień
- Sprawdzanie Lint: usługa eksportowana nie wymaga uprawnień