Kategoria OWASP: MASVS-CODE: jakość kodu
Omówienie
Używanie PendingIntent.getCreator*()
lub PendingIntent.getTarget*()
do określania, czy nadawcy obiektu PendingIntent można zaufać, stwarza ryzyko wykorzystania.
PendingIntent.getCreator*()
lub
PendingIntent.getTarget*()
zwraca twórcę PendingIntent, który nie zawsze jest zgodny z jego nadawcą. Twórca może być zaufany, ale nadawca nigdy nie powinien być zaufany, ponieważ może to być szkodliwa aplikacja, która uzyskała obiekt PendingIntent innej aplikacji za pomocą różnych mechanizmów, np.:
- od
NotificationListenerService
- prawidłowe przypadki użycia, które są częścią podatnej na ataki aplikacji.
Przykładem prawidłowego użycia PendingIntent.getCreator*()
lub PendingIntent.getTarget*()
jest wyświetlanie ikony aplikacji, która zostanie uruchomiona przez PendingIntent.
Wpływ
Ufanie nadawcy obiektu PendingIntent, ponieważ zapytano o twórcę (i mu się ufa), może prowadzić do luk w zabezpieczeniach. Jeśli aplikacja ufa nadawcy PendingIntent na podstawie jego twórcy, a następnie udostępnia logikę uwierzytelniania lub autoryzacji, to w przypadku gdy nadawcą PendingIntent jest złośliwa aplikacja, może to prowadzić do obejścia uwierzytelniania lub potencjalnie nawet do zdalnego wykonania kodu na podstawie nieprawidłowych, niezaufanych danych wejściowych, w zależności od implementacji kodu podatnej na ataki aplikacji.
Środki ograniczające ryzyko
Rozróżnianie nadawcy i twórcy
Żadna logika uwierzytelniania ani autoryzacji wykonywana podczas odbierania obiektu PendingIntent nie może opierać się na założeniach dotyczących twórcy obiektu PendingIntent zidentyfikowanego za pomocą PendingIntent.getCreator*()
lub PendingIntent.getTarget*()
.
Używanie alternatywnych sposobów weryfikacji dzwoniących
Jeśli musisz uwierzytelnić wywołującego, zamiast PendingIntent użyj usługi lub ContentProvider – oba te elementy umożliwiają pobranie identyfikatora UID wywołującego za pomocą Binder.getCallingUid() w kontekście wysyłania przychodzącego IPC. Identyfikator UID można później wysłać w zapytaniu za pomocą metody PackageManager.getPackagesForUid().
Innym podejściem, dostępnym od poziomu API 34, jest użycie funkcji BroadcastReceiver.getSentFromUid() lub BroadcastReceiver.getSentFromPackage(), jeśli nadawca zgodził się na udostępnianie tożsamości podczas transmisji za pomocą funkcji BroadcastOptions.isShareIdentityEnabled().
Zawsze sprawdzaj, czy pakiet wywołujący ma oczekiwany podpis, ponieważ pakiety wczytywane z zewnątrz mogą mieć nazwy pakietów pokrywające się z nazwami pakietów ze Sklepu Play.