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 los llamadores externos.
Por lo general, la vulnerabilidad se refiere a instancias en las que el receptor de emisión se exporta de forma no intencional, ya sea configurando android:exported="true"
en AndroidManifest o creando un receptor de emisión 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"
.
Se puede hacer un uso inadecuado de los receptores de emisión exportados de forma intencional sin un control de acceso adecuado si el desarrollador no tenía la intención de que todas las aplicaciones lo llamaran.
Impacto
Un atacante puede abusar de 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 tenía la intención de exponer a terceros.
Mitigaciones
Evita el problema por completo
Para resolver el dilema por completo, establece exported
en false
:
<receiver android:name=".MyReceiver" android:exported="false">
<intent-filter>
<action android:name="com.example.myapp.MY_ACTION" />
</intent-filter>
</receiver>
Cómo usar llamadas y devoluciones de llamada
En el caso de que hayas usado receptores de emisión para fines internos de la app (p. ej., una notificación de finalización de evento), puedes reestructurar tu código para pasar una devolución de llamada que se active 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
// ...
}
}
Cómo proteger los receptores de emisión con permisos
Solo registra receptores dinámicos para transmisiones protegidas (transmisiones que solo pueden enviar las aplicaciones a nivel del sistema) o con permisos a nivel de la firma autodeclarados.
Recursos
- Elementos del receptor exportados
- Documentación de los permisos del receptor de emisión
- Intents de transmisión protegidos