Kategoria OWASP: MASVS-CODE: Code Quality
Omówienie
Zagrożenia związane z uprawnieniami niestandardowymi pojawiają się, gdy definicja uprawnień niestandardowych jest nieobecna lub zawiera błędy lub gdy w manifeście niewłaściwie użyto atrybutu android:protectionLevel
.
Ryzyko to można wykorzystać, tworząc niestandardowe uprawnienie o tej samej nazwie, ale zdefiniowane przez złośliwą aplikację i z różnymi poziomami ochrony.
Uprawnienia niestandardowe umożliwiają udostępnianie zasobów i możliwości innym aplikacjom. Przykłady uzasadnionego używania niestandardowych uprawnień:
- kontrolowanie komunikacji między procesami (IPC) między co najmniej 2 aplikacjami;
- Dostęp do usług innych firm
- Ograniczanie dostępu do udostępnionych danych aplikacji
Wpływ
Wykorzystanie tej luki może spowodować, że złośliwa aplikacja uzyska dostęp do zasobów, które miały być chronione. Skutki tej podatności zależą od chronionego zasobu i powiązanych z pierwotną usługą aplikacji uprawnień.
Zagrożenie: błędy w niestandardowych uprawnieniach
W pliku manifestu może być zadeklarowane niestandardowe uprawnienie, ale do ochrony wyeksportowanych komponentów Androida używane jest inne niestandardowe uprawnienie z powodu pomyłki. Złośliwa aplikacja może wykorzystać aplikacje, które mają błędnie zapisane uprawnienie, w ten sposób:
- Najpierw zarejestruj to uprawnienie
- przewidywanie pisowni w kolejnych aplikacjach;
Może to umożliwić aplikacji nieautoryzowany dostęp do zasobów lub kontrolę nad aplikacją ofiary.
Na przykład aplikacja z luką chce chronić komponent za pomocą uprawnienia READ_CONTACTS
, ale przypadkowo źle je zapisuje jako READ_CONACTS
. Złośliwa aplikacja może zgłosić prawa do READ_CONACTS
, ponieważ nie jest własnością żadnej aplikacji (ani systemu) i może uzyskać dostęp do chronionego komponentu. Innym częstym wariantem tej podatności jest android:permission=True
. Wartości takie jak true
i false
, niezależnie od wielkości liter, są nieprawidłowymi danymi w deklaracji uprawnień i są traktowane podobnie jak inne błędy w deklaracji uprawnień niestandardowych. Aby to naprawić, wartość atrybutu android:permission
należy zmienić na prawidłowy ciąg znaków uprawnień. Jeśli na przykład aplikacja musi mieć dostęp do kontaktów użytkownika, wartość atrybutu android:permission
powinna wynosić android.permission.READ_CONTACTS
.
Środki zaradcze
Sprawdzanie Android Lint
Podczas deklarowania niestandardowych uprawnień korzystaj z Androida Lint, aby znajdować w kodzie literówki i inne potencjalne błędy.
Konwencja nazewnictwa
Stosuj spójną konwencję nazewnictwa, aby ułatwić zauważenie literówek. Uważnie sprawdź deklaracje niestandardowych uprawnień w pliku manifestu aplikacji pod kątem literówek.
Ryzyko: osieroczone uprawnienia
Uprawnienia służą do ochrony zasobów aplikacji. Aplikacja może deklarować uprawnienia wymagane do dostępu do zasobów w 2 miejscach:
- AndroidManifest.xml: zdefiniowane w pliku AndroidManifest.xml (jeśli nie są określone, używane są uprawnienia
<application>
), np. uprawnienie dostawcy, uprawnienie odbiornika, uprawnienie aktywności, uprawnienie usługi; - Kod: zarejestrowany w kodzie środowiska wykonawczego, np.
registerReceiver()
.
Czasami jednak te uprawnienia nie są zdefiniowane za pomocą odpowiedniego tagu <permission>
w pliku manifestu pakietu APK na urządzeniu. W takim przypadku są one nazywane uprawnieniami bez właściciela. Może się to zdarzyć z kilku powodów, na przykład:
- Może wystąpić rozbieżność między aktualizacjami w pliku manifestu a kodem w zakresie sprawdzania uprawnień.
- Plik APK z uprawnieniami może nie być uwzględniony w kompilacji lub może zawierać niewłaściwą wersję.
- Nazwy uprawnień w kontroli lub pliku manifestu mogą być napisane niepoprawnie.
Złośliwa aplikacja może zdefiniować osieroczone uprawnienie i je uzyskać. Jeśli tak się stanie, aplikacje z przywilejami, które ufają tej osieroconej uprawnieniu do ochrony komponentu, mogą zostać naruszone.
W przypadku, gdy aplikacja uprzywilejowana używa uprawnienia do ochrony lub ograniczenia dowolnego komponentu, może to przyznać złośliwej aplikacji dostęp do tego komponentu. Przykłady obejmują uruchamianie działań chronionych przez uprawnienie, dostęp do dostawcy treści lub nadawanie do odbiornika chronionego przez uprawnienie bez właściciela.
Może to też spowodować, że aplikacja z przywilejami zostanie oszukana i uwierzy, że złośliwa aplikacja jest legalna, a następnie wczyta pliki lub treści.
Środki zaradcze
Upewnij się, że wszystkie niestandardowe uprawnienia, których aplikacja używa do ochrony komponentów, są również zdefiniowane w pliku manifestu.
Aplikacja używa niestandardowych uprawnień my.app.provider.READ
i my.app.provider.WRITE
, aby chronić dostęp do dostawcy treści:
Xml
<provider android:name="my.app.database.CommonContentProvider" android:readPermission="my.app.provider.READ" android:writePermission="my.app.provider.WRITE" android:exported="true" android:process=":myappservice" android:authorities="my.app.database.contentprovider"/>
Aplikacja definiuje i wykorzystuje te niestandardowe uprawnienia, uniemożliwiając innym złośliwym aplikacjom robienie tego samego:
Xml
<permission android:name="my.app.provider.READ"/>
<permission android:name="my.app.provider.WRITE"/>
<uses-permission android:name="my.app.provider.READ" />
<uses-permission android:name="my.app.provider.WRITE" />
Zagrożenie: niewłaściwe użycie android:protectionLevel
Ten atrybut opisuje potencjalny poziom ryzyka związanego z uprawnieniem i określa, jakie procedury powinien wykonać system, aby podjąć decyzję o przyznaniu uprawnienia.
Środki zaradcze
Unikaj poziomu ochrony Normalna lub Niebezpieczna
Użycie normalnych lub niebezpiecznych protectionLevel
uprawnień oznacza, że większość aplikacji może prosić o te uprawnienia i je uzyskać:
- W przypadku wartości „normal” wystarczy tylko ją zadeklarować.
- „dangerous” (niebezpieczne) zostanie zatwierdzone przez wielu użytkowników.
Dlatego te protectionLevels
zapewniają niewielkie bezpieczeństwo.
Używanie uprawnień do podpisu cyfrowego (Android >= 10)
W miarę możliwości używaj poziomów ochrony podpisu. Dzięki temu tylko inne aplikacje podpisane tym samym certyfikatem co aplikacja, która utworzyła uprawnienie, będą mogły uzyskać dostęp do tych chronionych funkcji. Upewnij się, że używasz dedykowanego (nieużywanego) certyfikatu podpisywania i bezpiecznie przechowujesz go w magazynie kluczy.
W pliku manifestu zdefiniuj uprawnienie niestandardowe w ten sposób:
Xml
<permission
android:name="my.custom.permission.MY_PERMISSION"
android:protectionLevel="signature"/>
Ogranicz dostęp do danej czynności tylko do tych aplikacji, które mają to uprawnienie niestandardowe, na przykład w ten sposób:
Xml
<activity android:name=".MyActivity" android:permission="my.custom.permission.MY_PERMISSION"/>
Każda inna aplikacja podpisana tym samym certyfikatem co aplikacja, która zadeklarowała to niestandardowe uprawnienie, będzie miała dostęp do aktywności .MyActivity
. Musisz zadeklarować to uprawnienie w swoim pliku manifestu w ten sposób:
Xml
<uses-permission android:name="my.custom.permission.MY_PERMISSION" />
Uważaj na uprawnienia do niestandardowych podpisów (Android < 10)
Jeśli Twoja aplikacja jest przeznaczona na Androida w wersji 10 lub niższej, to gdy uprawnienia niestandardowe zostaną usunięte z powodu odinstalowania lub aktualizacji, złośliwe aplikacje mogą nadal korzystać z tych uprawnień, omijając w ten sposób kontrole. Wynika to z luki w zabezpieczeniach dotyczącej eskalacji uprawnień (CVE-2019-2200
), która została naprawiona w Androidzie 10.
Jest to jeden z powodów (obok ryzyka wystąpienia warunków wyścigu), dla których zalecamy sprawdzanie podpisów zamiast uprawnień niestandardowych.
Ryzyko: sytuacja wyścigu
Jeśli legalna aplikacja A
definiuje niestandardowe uprawnienie sygnatury, które jest używane przez inne aplikacje X
, ale zostaje później odinstalowane, szkodliwa aplikacja B
może zdefiniować to samo niestandardowe uprawnienie z innym protectionLevel
, np. normal. W ten sposób aplikacja B
uzyska dostęp do wszystkich komponentów chronionych przez to niestandardowe uprawnienie w aplikacjach X
bez konieczności podpisania ich tym samym certyfikatem co aplikacja A
.
To samo dzieje się, gdy B
zostanie zainstalowany przed A
.
Środki zaradcze
Jeśli chcesz udostępnić komponent tylko aplikacjom podpisanym tym samym podpisem co aplikacja dostarczająca, możesz nie definiować niestandardowych uprawnień, aby ograniczyć dostęp do tego komponentu. W takim przypadku możesz użyć weryfikacji podpisu. Gdy jedna z Twoich aplikacji wysyła żądanie do innej, ta druga może sprawdzić, czy obie są podpisane tym samym certyfikatem, zanim spełni żądanie.
Materiały
- Minimalizowanie liczby próśb o uprawnienia
- Omówienie uprawnień
- Opis poziomów ochrony
- CustomPermissionTypo Android Lint
- Jak korzystać z Android Lint
- Artykuł naukowy z szczegółowym wyjaśnieniem uprawnień w Androidzie i ciekawymi wynikami testów fuzz