Categoria do OWASP: MASVS-PLATFORM - Interação com plataformas
Visão geral
Broadcast receivers implementados incorretamente 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 casos em que o broadcast receiver é
exportado acidentalmente, seja definindo android:exported="true"
no
AndroidManifest ou criando um broadcast receiver de forma programática, o que
torna o receiver público por padrão. Se o receptor não tiver filtros de
intent, o valor padrão será "false"
. No entanto, se o receptor tiver pelo menos um
filtro de intent, o valor padrão de android:exported será "true"
.
Os broadcast receivers exportados intencionalmente sem o controle de acesso adequado podem ser abusados se o desenvolvedor não pretendia que eles fossem chamados por todos os apps.
Impacto
Os broadcast receivers implementados de forma não segura podem ser abusados por um invasor para ter acesso não autorizado para executar um comportamento no aplicativo que o desenvolvedor não pretendia expor a terceiros.
Mitigações
Evitar o problema completamente
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
No caso de uso de broadcast receivers para fins internos do app (por exemplo, notificação de conclusão de evento), é possível reestruturar o código para transmitir um callback que seria 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
Só registre 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 do receptor exportados
- Documentação sobre permissões de broadcast receiver
- Intents de transmissão protegidas