Kategoria OWASP: MASVS-CODE: jakość kodu
Omówienie
Zagrożenia związane z uprawnieniami niestandardowymi występują, gdy brakuje definicji uprawnień niestandardowych lub jest ona zapisana z błędem albo gdy w pliku manifestu jest użyty odpowiedni atrybut android:protectionLevel
.
Na przykład można wykorzystać te zagrożenia, 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 korzystania z uprawnień niestandardowych:
- kontrolowanie komunikacji między procesami (IPC) między co najmniej 2 aplikacjami;
- Uzyskiwanie dostępu do usług innych firm
- Ograniczanie dostępu do udostępnianych 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ń.
Ryzyko: niestandardowe literówki w 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ć własność elementu READ_CONACTS
, ponieważ nie jest on własnością żadnej aplikacji (ani systemu) i uzyskuje 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 wejściowymi deklaracji uprawnień i są traktowane podobnie jak inne literówki w deklaracji uprawnień. 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ń użyj kontroli Androida Lint, aby znaleźć w kodzie literówki i inne potencjalne błędy.
Konwencja nazewnictwa
Stosuj spójną konwencję nazewnictwa, aby ułatwić zauważanie literówek. Uważnie sprawdź deklaracje niestandardowych uprawnień w pliku manifestu aplikacji pod kątem literówek.
Ryzyko: osierocone uprawnienia
Uprawnienia służą do ochrony zasobów aplikacji. Aplikacja może zadeklarować uprawnienia wymagane do uzyskiwania dostępu do zasobów w 2 różnych 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 przez odpowiedni tag <permission>
w pliku manifestu pakietu APK na urządzeniu. W takim przypadku są one nazywane osieroconymi uprawnieniami. Taka sytuacja może mieć wiele
powodów, na przykład:
- Między aktualizacjami w pliku manifestu a kodem ze sprawdzaniem uprawnień może wystąpić rozbieżność
- Plik APK z odpowiednimi uprawnieniami może nie zostać uwzględniony w kompilacji lub może w niej znaleźć niewłaściwą wersję.
- Nazwa uprawnienia w sprawdzonym pliku lub pliku manifestu może być zapisana niepoprawnie.
Złośliwa aplikacja może zdefiniować osieroczone uprawnienie i je uzyskać. Jeśli tak się stanie, może dojść do przejęcia aplikacji z podwyższonymi uprawnieniami, które ufają osieroconym uprawnieniom do ochrony komponentu.
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.
Łagodzenie
Unikaj poziomu ochrony Normalna lub Niebezpieczna
Użycie normalnego lub niebezpiecznego protectionLevel
w uprawnieniach oznacza, że większość aplikacji może poprosić o te uprawnienia i je uzyskać:
- W przypadku wartości „normal” wystarczy tylko ją zadeklarować.
- „dangerous” zostanie zatwierdzona przez wielu użytkowników.
Dlatego te protectionLevels
zapewniają znikome 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: warunki 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. Dzięki temu B
uzyska dostęp do wszystkich komponentów chronionych przez to niestandardowe uprawnienie w aplikacjach X
bez konieczności podpisywania ich tym samym certyfikatem co aplikacja A
.
Podobnie dzieje się, gdy B
zostanie zainstalowany przed A
.
Środki zaradcze
Jeśli chcesz, aby komponent był dostępny tylko w przypadku aplikacji podpisanych tym samym podpisem co aplikacja udostępniająca, możesz unikać definiowania niestandardowych uprawnień ograniczających dostęp do tego komponentu. W tej sytuacji możesz skorzystać z weryfikacji podpisu. Gdy jedna z aplikacji wyśle żądanie dotyczące innej aplikacji, druga aplikacja może przed wykonaniem żądania sprawdzić, czy obie są podpisane tym samym certyfikatem.
Materiały
- Minimalizowanie liczby próśb o uprawnienia
- Przegląd 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