Eliminacja luki w zabezpieczeniach typu „przekierowanie intencji”

Te informacje są przeznaczone dla deweloperów aplikacji, które zawierają lukę w zabezpieczeniach typu „przekierowanie intencji”.

O co chodzi?

W co najmniej jednej z Twoich aplikacji występuje problem z przekierowaniem intencji, przez co złośliwe aplikacje mogą mieć dostęp do prywatnych komponentów lub plików Twojej aplikacji. Wykonaj dokładnie podane niżej czynności, by rozwiązać ten problem. Po przekroczeniu terminów wskazanych w Konsoli Play wszystkie aplikacje z lukami w zabezpieczeniach zostaną usunięte z Google Play.

Wymagane działania​

  1. Zaloguj się w Konsoli Play i przejdź do sekcji Alerty, by sprawdzić, których aplikacji dotyczy problem i jaki jest termin jego rozwiązania.
  2. Zaktualizuj aplikacje, których dotyczy problem, w sposób opisany poniżej.
  3. Prześlij zaktualizowane wersje tych aplikacji.

Po ponownym przesłaniu aplikacja zostanie jeszcze raz sprawdzona. Ten proces może potrwać kilka godzin. Jeśli aplikacja pomyślnie przejdzie weryfikację i zostanie opublikowana, nie musisz już nic robić. Jeśli wynik weryfikacji nie będzie pomyślny, nowa wersja aplikacji nie zostanie opublikowana, a Ty otrzymasz powiadomienie e-mailem.

Dodatkowe szczegóły

Używanie niezaufanej intencji do uruchamiania komponentu (np. przez wywołanie metody startActivity) lub do zwracania danych (np. przez wywołanie metody setResult) jest niebezpieczne i może pozwolić złośliwym aplikacjom na takie działania jak: 

  1. kradzież poufnych plików lub danych systemowych (np. SMS-ów) z aplikacji,
  2. uruchamianie prywatnych komponentów aplikacji przy użyciu zatrutych argumentów.

Aplikacja nie powinna wywoływać metod startActivity, startService, sendBroadcast ani setResult z niezaufanymi intencjami bez ich wcześniejszej weryfikacji lub sanityzacji.

Aby zabezpieczyć aplikacje przed atakiem wykorzystującym tę lukę, użyj jednego z tych rozwiązań:

Opcja 1. Ustaw komponent aplikacji, z którego przekierowywana jest wyodrębniona intencja, jako prywatny

Jeśli komponent, którego dotyczy problem, nie musi odbierać intencji z innych aplikacji, możesz określić go jako prywatny, ustawiając w pliku manifestu funkcję android:exported=”false”.

Opcja 2. Sprawdź, czy wyodrębniona intencja pochodzi z wiarygodnego źródła

Możesz sprawdzić, czy aktywność źródłowa jest godna zaufania, używając metod takich jak getCallingActivity. Przykład:

 // Sprawdź, czy aktywność źródłowa pochodzi z zaufanego pakietu
 if (getCallingActivity().getPackageName().equals(“known”)) {
   Intent intent = getIntent();
   // Wyodrębnij umieszczoną intencję
   Intent forward = (Intent) intent.getParcelableExtra(“key”);
   // Przekieruj umieszczoną intencję
   startActivity(forward);
 }

Uwaga:

  • Sprawdzenie, czy funkcja getCallingActivity() zwraca niepustą wartość, nie wystarcza do tego, by zapobiec wystąpieniu luki w zabezpieczeniach. Złośliwe aplikacje mogą dostarczyć pustą wartość dla tej funkcji.
  • W przypadku interfejsu SMS Retriever API Usług Google Play ochrona odbiornika za pomocą uprawnienia SEND_PERMISSION pozwala się upewnić, że intencja pochodzi z Usług Google Play.

Opcja 3. Sprawdź, czy intencja do przekierowania nie jest szkodliwa

Sprawdź, czy przekierowana intencja:

  1. nie zostanie wysłana do żadnego z prywatnych komponentów aplikacji,
  2. nie zostanie wysłana do komponentu aplikacji zewnętrznej. Jeśli przekierowanie jest przeznaczone dla aplikacji zewnętrznej, upewnij się, że intencja nie przyznaje uprawnień dotyczących identyfikatora URI jednemu z prywatnych dostawców treści w Twojej aplikacji ani danym systemowym.

Aplikacje mogą sprawdzać, który komponent będzie używany do obsługi intencji przed jej przekierowaniem, korzystając z takich metod jak resolveActivity. Przykład:

 Intent intent = getIntent();
 // Wyodrębnij umieszczoną intencję
 Intent forward = (Intent) intent.getParcelableExtra(“key”);
 // Pobierz nazwę komponentu
 ComponentName name = forward.resolveActivity(getPackageManager());
 // Sprawdź, czy nazwy pakietu i klasy wyglądają tak, jak powinny
 if (name.getPackageName().equals(“safe_package”) &&
     name.getClassName().equals(“safe_class”)) {
   // Przekieruj umieszczoną intencję
   startActivity(forward);
 }

Aplikacje mogą sprawdzać, czy intencja przyznaje uprawnienia dotyczące identyfikatora URI, korzystając z takich metod jak getFlags. Przykład:

 // Wyodrębnij umieszczoną intencję
 Intent forward = (Intent) intent.getParcelableExtra(“key”);
 // Pobierz flagi
 int flags = forward.getFlags();
 // Upewnij się, że umieszczona intencja nie przyznaje uprawnień dotyczących identyfikatora URI
 if ((flags & Intent.FLAG_GRANT_READ_URI_PERMISSION == 0) &&
     (flags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION == 0)) {
   // Przekieruj umieszczoną intencję
   startActivity(forward);
 }

Aplikacje mogą też usuwać przyznane uprawnienia tego typu za pomocą metody removeFlags. Przykład:

 // Niezaufana intencja
 Intent intent = getIntent();
 // Usuń przyznane uprawnienia do identyfikatora URI w niezaufanej intencji
 intent.removeFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
 intent.removeFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
 // Przekaż niezaufaną intencję
 setResult(intent);

Informacje o alertach i wybieranie metod zaradczych

Jeśli Twoja aplikacja wywołuje metodę startActivity, startActivityForResult, startService, sendBroadcast lub setResult przy użyciu niezaufanej intencji, Konsola Play powiadamia o tym alertem. Aby dowiedzieć się, która opcja ochrony przed takim działaniem jest najlepsza, przejrzyj elementy wywołujące metody, żeby odkryć, skąd pochodzi niezaufana intencja. W przypadku opcji 1 możesz na przykład prześledzić działania, żeby sprawdzić, jaki komponent należy ustawić jako prywatny.

Chętnie Ci pomożemy

Jeśli masz pytania techniczne związane z tą luką w zabezpieczeniach, możesz je opublikować na stronie Stack Overflow, używając tagu „android-security”. Jeśli potrzebujesz wyjaśnienia czynności niezbędnych do rozwiązania tego problemu, skontaktuj się z naszym zespołem pomocy dla deweloperów.

Czy to było pomocne?

Jak możemy ją poprawić?
false
Menu główne
1269926705969775272
true
Wyszukaj w Centrum pomocy
true
true
true
true
true
5016068
false
false