Uprawnienia niestandardowe

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:

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