Categoria do OWASP: MASVS-PLATFORM - Interação com plataformas
Visão geral
Broadcast receivers implementados de forma inadequada podem permitir que um invasor envie uma intent maliciosa para fazer com que o aplicativo vulnerável execute ações que não são destinadas a chamadores externos.
A vulnerabilidade geralmente se refere a instâncias em que o broadcast receiver é
exportado sem intenção, seja definindo android:exported="true" no
AndroidManifest ou criando um broadcast receiver de forma programática, o que
torna o receptor público por padrão. Se o receptor não tiver filtros de intent, o valor padrão será "false". Se ele tiver pelo menos um filtro de intent, o valor padrão de android:exported será "true".
Os broadcast receivers exportados intencionalmente sem controle de acesso adequado podem ser usados indevidamente se o desenvolvedor não tiver a intenção de que ele seja chamado por todos os aplicativos.
Impacto
Os broadcast receivers implementados de forma insegura podem ser usados indevidamente por um invasor para ganhar acesso não autorizado e executar comportamentos no aplicativo que o desenvolvedor não pretendia expor a terceiros.
Mitigações
Evitar o problema
Para resolver o dilema completamente, defina exported como false:
<receiver android:name=".MyReceiver" android:exported="false">
<intent-filter>
<action android:name="com.example.myapp.MY_ACTION" />
</intent-filter>
</receiver>
Usar chamadas e callbacks
Se você usou broadcast receivers para fins internos do app (por exemplo, notificação de conclusão de evento), reestruture o código para transmitir um callback que seja acionado após a conclusão do evento.
Listener de conclusão de eventos
Kotlin
interface EventCompletionListener {
fun onEventComplete(data: String)
}
Java
public interface EventCompletionListener {
public void onEventComplete(String data);
}
Tarefa 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");
}
}
}
Atividade 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
// ...
}
}
Proteger broadcast receivers com permissões
Registre apenas receptores dinâmicos para transmissões protegidas (transmissões que só aplicativos no nível do sistema podem enviar) ou com permissões de nível de assinatura autodeclaradas.
Recursos
- Elementos de receptor exportados
- Documentação sobre permissões de broadcast receiver
- Intents de transmissão protegidas