Kategoria OWASP: MASVS-PLATFORM: Platform Interaction
Przegląd
Uprawnienie Androida to identyfikator w postaci ciągu znaków zadeklarowany w manifeście aplikacji, który służy do żądania dostępu do danych lub działań o ograniczonym dostępie. Jest on egzekwowany w czasie działania przez platformę Androida.
Poziomy uprawnień Androida wskazują potencjalne ryzyko związane z uprawnieniami:
- Normalne: uprawnienia o niskim ryzyku, przyznawane automatycznie podczas instalacji.
- Niebezpieczne: uprawnienia wysokiego ryzyka, które mogą umożliwiać dostęp do wrażliwych danych użytkownika i wymagają wyraźnej zgody użytkownika w czasie działania aplikacji.
- Podpis: przyznawane tylko aplikacjom podpisanym tym samym certyfikatem co aplikacja deklarująca uprawnienia. Zwykle używane w przypadku aplikacji systemowych lub interakcji między aplikacjami tego samego dewelopera.
Luki w zabezpieczeniach związane z kontrolą dostępu opartą na uprawnieniach występują, gdy komponent aplikacji (np. aktywność, odbiornik, dostawca treści lub usługa) spełnia wszystkie te kryteria:
- komponent nie jest powiązany z żadnym elementem
android:permissionwManifest; - komponent wykonuje zadanie związane z poufnymi danymi, do którego istnieje uprawnienie, które użytkownik już zatwierdził;
- Komponent jest eksportowany.
- Komponent nie przeprowadza żadnych ręcznych kontroli uprawnień (na poziomie pliku manifestu ani kodu);
W takim przypadku złośliwa aplikacja może wykonywać działania wymagające dostępu do informacji poufnych, wykorzystując uprawnienia podatnego na ataki komponentu i przekazując je do złośliwej aplikacji.
Wpływ
Eksportowanie podatnych na ataki komponentów może służyć do uzyskiwania dostępu do zasobów wrażliwych lub wykonywania działań związanych z poufnymi danymi. Wpływ tego niepożądanego zachowania zależy od kontekstu podatnego na ataki komponentu i jego uprawnień.
Środki ograniczające ryzyko
Wymaganie uprawnień do wykonywania działań związanych z danymi poufnymi
Podczas eksportowania komponentu z uprawnieniami dostępu do informacji poufnych wymagaj tych samych uprawnień w przypadku każdego przychodzącego żądania. Środowisko IDE Android Studio ma testy lint dla odbiorników i usług, które pozwalają wykryć tę lukę w zabezpieczeniach i zalecają wymaganie odpowiednich uprawnień.
Programiści mogą wymagać uprawnień w przypadku przychodzących żądań, deklarując je w pliku Manifest lub na poziomie kodu podczas wdrażania usługi, jak w poniższych przykładach.
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 wrażliwych, chyba że jest to absolutnie konieczne. Aby to zrobić, ustaw wartość android:exported w pliku Manifest na false w przypadku komponentu. Od poziomu API 31 ten atrybut jest domyślnie ustawiony na wartość false.
XML
<activity
android:name=".MyActivity"
android:exported="false"/>
Stosowanie uprawnień na podstawie podpisu
Podczas udostępniania danych między 2 aplikacjami, które kontrolujesz lub których jesteś właścicielem, używaj uprawnień opartych na sygnaturze. Te uprawnienia nie wymagają potwierdzenia przez użytkownika, ale sprawdzają, czy aplikacje uzyskujące dostęp do danych są podpisane tym samym kluczem podpisu. Ta konfiguracja zapewnia bardziej uproszczone i bezpieczne korzystanie z usługi. Jeśli deklarujesz uprawnienia niestandardowe, zapoznaj się z odpowiednimi wytycznymi 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ą projektowania Separation of Concerns. Każdy punkt końcowy powinien wykonywać tylko niewielki zestaw określonych zadań z określonymi uprawnieniami. Ta dobra praktyka projektowania umożliwia też programiście stosowanie szczegółowych uprawnień do każdego punktu końcowego. Nie należy na przykład tworzyć jednego punktu końcowego, który obsługuje zarówno kalendarz, jak i kontakty.
Zasoby
- Android Access to app protected components from the Oversecured blog
- Sprawdzone metody dla dostawców treści
- Uprawnienia czasu działania (niebezpieczne)
- Zasada projektowania „Separation of Concerns”
- Dokumentacja uprawnień na Androidzie
- Wskazówki dotyczące bezpieczeństwa odbiorników transmisji w Androidzie
- Wskazówki dotyczące bezpieczeństwa usług na Androidzie
- Android 12 (API 31) wyeksportował domyślny zbiór ustawiony na „false”
- Lint Check: Exported PreferenceActivity shouldn't be exported
- Lint Check: wyeksportowany odbiorca nie wymaga uprawnień
- Lint Check: wyeksportowana usługa nie wymaga uprawnień