04 Broadcast 安全与跨应用通信最佳实践

基于原 PDF 修订、联网校对并补充缺失内容

1. Broadcast 安全模型的核心问题

Broadcast 的 action 命名空间是全局的,隐式广播可能被任何匹配的应用接收;导出的 receiver 也可能被其他应用伪造广播触发。因此,Broadcast 一定要同时考虑“谁能收到我发的广播”和“谁能给我发广播”。

风险 表现 防护
敏感信息泄漏 使用隐式广播发送 token、订单号、用户资料等 不要发敏感数据;必要时 setPackage/显式组件/权限保护。
伪造广播触发逻辑 导出 receiver 被恶意应用发送相同 action 激活 android:exported=“false”;校验 permission、签名、来源与 extras。
Action 冲突 多个应用使用同名自定义 action 使用包名前缀命名 action。
后台滥用 receiver 里执行长任务或拉起 Activity 快速返回,转交 WorkManager/JobScheduler,用通知而不是直接启动页面。

2. 发送广播时如何限制接收方

  • 优先显式化:intent.setPackage(packageName) 或 intent.setComponent(ComponentName(…))。
  • 使用发送权限:sendBroadcast(intent, “com.example.permission.PRIVATE”)。
  • 不要通过隐式广播发送敏感 extras。
  • 对外协议要版本化,extras 使用稳定 key,并做好缺字段与类型错误处理。
// 只发给本应用包内匹配的 receiver
Intent intent = new Intent("com.example.app.ACTION_LOGOUT");
intent.setPackage(context.getPackageName());
context.sendBroadcast(intent);
// 使用权限保护接收方:只有持有该权限的 receiver 才能接收
context.sendBroadcast(intent, "com.example.permission.INTERNAL_BROADCAST");

3. 接收广播时如何限制发送方

<!-- Manifest receiver:默认不对外暴露 -->
<receiver
    android:name=".InternalReceiver"
    android:exported="false" />

<!-- 对外 receiver:用权限限制调用方 -->
<receiver
    android:name=".PartnerReceiver"
    android:exported="true"
    android:permission="com.example.permission.PARTNER_BROADCAST">
    <intent-filter>
        <action android:name="com.example.partner.ACTION_PAY_RESULT" />
    </intent-filter>
</receiver>

动态注册时,内部事件优先使用 RECEIVER_NOT_EXPORTED;确实要接收外部应用或某些特权系统应用广播时才使用 RECEIVER_EXPORTED,并按需要加 receiverPermission。

4. 内部事件不一定要用 Broadcast

场景 推荐方案 理由
ViewModel 通知 Activity/Fragment LiveData、StateFlow、SharedFlow 类型安全,生命周期友好。
模块间事件 接口回调、Flow、事件总线 不需要 Intent 序列化,也不依赖系统广播机制。
跨进程通信 Binder/AIDL、Messenger、ContentProvider 明确 IPC 边界,类型与权限更可控。
系统事件触发后台任务 Manifest receiver + WorkManager/JobScheduler 符合后台限制,可靠性更好。
通知用户打开页面 Notification + PendingIntent 不要从 receiver 直接启动 Activity。

5. 跨应用广播协议设计清单

  1. action 使用包名前缀:com.company.product.ACTION_XXX。
  2. 明确 exported:默认 false;对外才 true。
  3. 使用签名级 permission 或 receiverPermission 控制调用方。
  4. extras 做完整校验:null、类型、范围、版本号都要处理。
  5. 不要相信广播来源;需要强身份时用绑定服务、AIDL 或服务端校验。
  6. onReceive 只做轻量解析和任务分发,不做网络请求和大 IO。

6. Sticky Broadcast 安全补充

Sticky Broadcast 的缓存和重放机制会带来“任何人可访问、可发送、可修改”的风险。现代应用不应使用 sticky broadcast 传递业务状态。

参考资料