Receptores de emisión no seguros

Categoría de OWASP: MASVS-PLATFORM: Interacción con la plataforma

Descripción general

Los receptores de emisión implementados de forma incorrecta pueden permitir que un atacante envíe un intent malicioso para que la aplicación vulnerable realice acciones que no están destinadas a quienes llaman de forma externa.

Por lo general, la vulnerabilidad se refiere a las instancias en las que el receptor de transmisiones se exporta de forma involuntaria, ya sea configurando android:exported="true" en el AndroidManifest o creando un receptor de transmisiones de forma programática, lo que hace que el receptor sea público de forma predeterminada. Si el receptor no contiene ningún filtro de intents , el valor predeterminado es "false", pero si el receptor contiene al menos un filtro de intents , el valor predeterminado de android:exported es "true".

Los receptores de emisión exportados de forma intencional sin un control de acceso adecuado se pueden usar de forma inadecuada si el desarrollador no pretendía que todas las aplicaciones los llamaran.

Impacto

Un atacante puede usar de forma inadecuada los receptores de emisión implementados de forma insegura para obtener acceso no autorizado y ejecutar un comportamiento en la aplicación que el desarrollador no pretendía exponer a terceros.

Mitigaciones

Evita el problema por completo

Para resolver el dilema por completo, configura exported como false:

<receiver android:name=".MyReceiver" android:exported="false">
    <intent-filter>
        <action android:name="com.example.myapp.MY_ACTION" />
    </intent-filter>
</receiver>

Usa llamadas y devoluciones de llamada

En caso de que hayas usado receptores de transmisiones para fines internos de la app (es decir, notificación de finalización de eventos), puedes reestructurar tu código para pasar una devolución de llamada que se activaría después de la finalización del evento.

Objeto de escucha de finalización de eventos

Kotlin

interface EventCompletionListener {
    fun onEventComplete(data: String)
}

Java

public interface EventCompletionListener {
    public void onEventComplete(String data);
}
Tarea segura

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");
        }
    }
}
Actividad principal

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
        // ...
    }
}

Protege los receptores de emisión con permisos

Solo registra receptores dinámicos para transmisiones protegidas (transmisiones que solo pueden enviar aplicaciones de nivel del sistema) o con permisos de nivel de firma autodeclarados.

Recursos