Niezabezpieczone odbiorniki

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