Kategoria OWASP: MASVS-PLATFORM: Platform Interaction
Przegląd
Nieprawidłowo zaimplementowane odbiorniki transmisji mogą umożliwić atakującemu wysłanie złośliwego zamiaru, aby aplikacja podatna na ataki wykonywała działania, które nie są przeznaczone dla zewnętrznych wywołujących.
Luka w zabezpieczeniach zwykle odnosi się do przypadków, w których odbiornik transmisji jest
nieumyślnie eksportowany przez ustawienie android:exported="true" w
pliku AndroidManifest lub przez utworzenie odbiornika transmisji programowo, co
domyślnie sprawia, że odbiornik jest publiczny. Jeśli odbiornik nie zawiera żadnych filtrów intencji, wartość domyślna to "false", ale jeśli odbiornik zawiera co najmniej 1 filtr intencji, wartość domyślna android:exported to "true".
Odbiorniki transmisji eksportowane celowo bez odpowiedniej kontroli dostępu mogą zostać wykorzystane, jeśli deweloper nie chciał, aby były wywoływane przez wszystkie aplikacje.
Wpływ
Atakujący może wykorzystać nieprawidłowo zaimplementowane odbiorniki transmisji, aby uzyskać nieautoryzowany dostęp do wykonywania w aplikacji działań, które deweloper nie chciał udostępniać osobom trzecim.
Środki zaradcze
Całkowite uniknięcie problemu
Aby całkowicie rozwiązać ten problem, ustaw exported na false:
<receiver android:name=".MyReceiver" android:exported="false">
<intent-filter>
<action android:name="com.example.myapp.MY_ACTION" />
</intent-filter>
</receiver>
Używanie wywołań i wywołań zwrotnych
Jeśli odbiorniki transmisji były używane do celów wewnętrznych aplikacji (np. powiadomienia o zakończeniu zdarzenia), możesz zmienić strukturę kodu, aby przekazywać wywołanie zwrotne, które będzie uruchamiane po zakończeniu zdarzenia.
Detektor zakończenia zdarzenia
Kotlin
interface EventCompletionListener {
fun onEventComplete(data: String)
}
Java
public interface EventCompletionListener {
public void onEventComplete(String data);
}
Bezpieczne zadanie
Kotlin
class SecureTask(private val listener: EventCompletionListener?) {
fun executeTask() {
// Do some work...
// Notify that the event is complete
listener?.onEventComplete("Some secure data")
}
}
Java
public class SecureTask {
final private EventCompletionListener listener;
public SecureTask(EventCompletionListener listener) {
this.listener = listener;
}
public void executeTask() {
// Do some work...
// Notify that the event is complete
if (listener != null) {
listener.onEventComplete("Some secure data");
}
}
}
Główna aktywność
Kotlin
class MainActivity : AppCompatActivity(), EventCompletionListener {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val secureTask = SecureTask(this)
secureTask.executeTask()
}
override fun onEventComplete(data: String) {
// Handle event completion securely
// ...
}
}
Java
public class MainActivity extends AppCompatActivity implements EventCompletionListener {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
SecureTask secureTask = new SecureTask(this);
secureTask.executeTask();
}
@Override
public void onEventComplete(String data) {
// Handle event completion securely
// ...
}
}
Zabezpieczanie odbiorników transmisji za pomocą uprawnień
Rejestruj odbiorniki dynamiczne tylko w przypadku transmisji chronionych (transmisji, które mogą wysyłać tylko aplikacje na poziomie systemu) lub z uprawnieniami na poziomie podpisu zadeklarowanymi samodzielnie.
Zasoby
- Wyeksportowane elementy odbiornika
- Dokumentacja uprawnień odbiornika transmisji
- Chronione intencje transmisji