AlarmManager 和 WakefullBroadcastReceiver 传递的 Extras 有多私密?
AlarmManager and WakefullBroadcastReceiver how private are the passed Extras?
我正在尝试使用 AlarmManager
实现一些警报调度。因为当警报被触发时,我想使用一个 WakefulBroadcastReceiver
启动一个 IntentService
来做一些后台工作。
我有一些问题与为警报意图传递的参数中的 security/privacy 有关。
在为闹钟设置 PendingIntent 时,我会执行以下操作:
Intent myIntent = new Intent(context, MyReceiver.class);
myIntent.putExtra("test", "testValue");
Bundle bundle = new Bundle();
bundle.putParcelable("bundleValue", bundleTestValue2);
myIntent.putExtra("test3", bundle);
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 323,
myIntent, PendingIntent.FLAG_UPDATE_CURRENT);
我的问题是:将警报的 pendingIntent 设置为 Extra
的值有多私密?由于 Android 警报管理器在安排后使用它们,是否有可能被其他应用程序读取?
通过
这样的接收器
public class MyReceiver extends WakefulBroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
startWakefulService(context, MyIntentService);
}
并在 android 清单上
<receiver
android:name=".receivers.MyReceiver"
android:exported="false"/>
<service
android:name=".MyIntentService"
android:exported="false"/>
和服务
public class MyIntentService extends IntentService {
@Override
protected void onHandleIntent(Intent intent) {
try {
//logic here
} catch{
} finaly{
MyReceiver.completeWakefulIntent(intent);
}
}
从我的 Activity
中调用
sendBroadcast(new Intent(context, MyReceiver.class).putExtra(...);
安排警报的未决意图
Intent myIntent = new Intent(context, MyReceiver.class);
myIntent.putExtra("test", "testValue");
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 323,
myIntent, PendingIntent.FLAG_UPDATE_CURRENT);
此接收器对其他应用的暴露程度如何?它可以对我以外的其他应用程序做出反应吗?这会引发任何可能的安全问题吗?
谢谢。
稍后编辑:
由于 WakefullBroadcastReceiver
似乎是保证我的服务将获得部分唤醒锁的唯一方法,我如何才能 100% 确保没有其他应用程序知道我的接收器并且我的接收器不会收到任何其他呼叫除了由我的 activity 或我的套装 Alarm
制作的?
WakefullBroadcastReceiver
模式与 CommonsWare 的 WakefulIntentService 相比如何工作?
稍后编辑:
我终于设法完成了我的实现。
如前所述,我的 WakefulBroadcastReceiver
和 IntentService
在我的 Android 清单中都被声明为 exported="false"
,据我所知,这意味着只有我的应用程序可以访问它们。由于receiver没有导出,是否接收到app外的广播?
设置闹钟时我用这个PendingIntent
:
Intent myIntent = new Intent(context, MyReceiver.class);<br>
myIntent.putExtra("databaseId", "1");
PendingIntent pendingIntent = PendingIntent.getBroadcast(上下文, 323,
myIntent, PendingIntent.FLAG_UPDATE_CURRENT);
当从我的 Activity 呼叫时,我会:
sendBroadcast(new Intent(context, MyReceiver.class).putExtra("databaseId", "1"));
够了吗?
与 Intent
额外内容相关的隐私注意事项
一般来说,我会说将敏感数据放在 Intent
中是一种不安全的做法。
理论上,如果 Intent
只能由特定应用程序(稍后讨论)使用,那么只有该应用程序应该能够看到其内容。但是,考虑到大量 Android 设备和 OS 版本(包括有根设备和自定义 ROM),我不会指望它。
您没有在 Intent
extras 中指定要传递的敏感数据类型,因此我只能给出这些一般性建议:
- 确保您了解相关数据的 "confidentiality level":它是秘密的,还是只是受限的?或者,也许是 public(在这种情况下不需要保护)?
- 尝试在
Intent
中寻找另一种不涉及传递敏感数据的方法(我自己从未遇到过这种需求)。
- 如果您绝对必须在
Intent
extras 中传递敏感数据 - 请考虑对其进行加密。加密模型应该足以 "confidentiality level" 的数据,以及如果数据被拦截可能造成的潜在危害(它可以一直达到 "server side" 加密)。
Privacy/security 与 BroadcastReceiver
有关的注意事项
一般来说,BroadcastReceiver
是一个接收"system wide"广播的组件。广播 "system wide" 本身应该说明与之相关的隐私级别。
也就是说,开发人员可以通过一种机制来限制广播的范围:自定义权限。使用自定义权限允许两个 "levels of control" 广播:
- 如果广播需要特定权限,那么只有
BroadcastReceiver
拥有该权限才能接收广播。
- 如果
BroadcastReceiver
通过特定权限过滤传入的广播,则只有带有该权限的广播才会传送到该接收者。
虽然以上几点乍一看很相似,但这些都是可以单独使用或组合使用的不同方案。第一种方案将广播与权限相关联(并且该广播的发送者自己不一定具有该权限),而第二种方案通过特定权限过滤所有广播(并且接收者必须具有该权限)。
您的情况更好的方法
编辑: 如果 "wakefullness" 不是要求的一部分,这可能是一个更好的方法。但它是。由于无法保证由 AlarmManager
启动的 Service
将有机会获得唤醒锁 - 这种方法不适合 OP 的情况。
请注意,广播和自定义权限的设计是为了在应用程序级别引入 "decoupling" - 这种方案允许发送方应用程序完全不知道接收方应用程序,只要他们同意一个自定义许可(好吧,同样的方案也适用于 pre-installed public 许可,但您不希望使用 public 许可来保护您的敏感数据)。
但是,在您的情况下,发送方和接收方是同一个应用程序。在这样的设置中,您真的不需要与广播相关的所有麻烦 - 只需构造 PendingIntent
即可在您的应用程序中启动所需的 Service
,您可以立即获得所有内容:
PendingIntent
和关联的 Intent
在您的应用程序中启动一个特定的 Service
(按名称),因此没有其他应用程序可以拦截它(理论上,请记住上面的讨论)。
- 目标
Service
可以是 non-exported,因此其他应用程序无法以任何方式访问它。
欢迎您:)
我正在尝试使用 AlarmManager
实现一些警报调度。因为当警报被触发时,我想使用一个 WakefulBroadcastReceiver
启动一个 IntentService
来做一些后台工作。
我有一些问题与为警报意图传递的参数中的 security/privacy 有关。
在为闹钟设置 PendingIntent 时,我会执行以下操作:
Intent myIntent = new Intent(context, MyReceiver.class); myIntent.putExtra("test", "testValue"); Bundle bundle = new Bundle(); bundle.putParcelable("bundleValue", bundleTestValue2); myIntent.putExtra("test3", bundle); PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 323, myIntent, PendingIntent.FLAG_UPDATE_CURRENT);
我的问题是:将警报的 pendingIntent 设置为 Extra
的值有多私密?由于 Android 警报管理器在安排后使用它们,是否有可能被其他应用程序读取?
通过
这样的接收器public class MyReceiver extends WakefulBroadcastReceiver {
@Override public void onReceive(Context context, Intent intent) { startWakefulService(context, MyIntentService); }
并在 android 清单上
<receiver
android:name=".receivers.MyReceiver"
android:exported="false"/>
<service
android:name=".MyIntentService"
android:exported="false"/>
和服务
public class MyIntentService extends IntentService {
@Override
protected void onHandleIntent(Intent intent) {
try {
//logic here
} catch{
} finaly{
MyReceiver.completeWakefulIntent(intent);
}
}
从我的 Activity
中调用sendBroadcast(new Intent(context, MyReceiver.class).putExtra(...);
安排警报的未决意图
Intent myIntent = new Intent(context, MyReceiver.class);
myIntent.putExtra("test", "testValue");
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 323,
myIntent, PendingIntent.FLAG_UPDATE_CURRENT);
此接收器对其他应用的暴露程度如何?它可以对我以外的其他应用程序做出反应吗?这会引发任何可能的安全问题吗?
谢谢。
稍后编辑:
由于 WakefullBroadcastReceiver
似乎是保证我的服务将获得部分唤醒锁的唯一方法,我如何才能 100% 确保没有其他应用程序知道我的接收器并且我的接收器不会收到任何其他呼叫除了由我的 activity 或我的套装 Alarm
制作的?
WakefullBroadcastReceiver
模式与 CommonsWare 的 WakefulIntentService 相比如何工作?
稍后编辑: 我终于设法完成了我的实现。
如前所述,我的
WakefulBroadcastReceiver
和IntentService
在我的 Android 清单中都被声明为exported="false"
,据我所知,这意味着只有我的应用程序可以访问它们。由于receiver没有导出,是否接收到app外的广播?设置闹钟时我用这个
PendingIntent
:Intent myIntent = new Intent(context, MyReceiver.class);<br> myIntent.putExtra("databaseId", "1"); PendingIntent pendingIntent = PendingIntent.getBroadcast(上下文, 323, myIntent, PendingIntent.FLAG_UPDATE_CURRENT);
当从我的 Activity 呼叫时,我会:
sendBroadcast(new Intent(context, MyReceiver.class).putExtra("databaseId", "1"));
够了吗?
与 Intent
额外内容相关的隐私注意事项
一般来说,我会说将敏感数据放在 Intent
中是一种不安全的做法。
理论上,如果 Intent
只能由特定应用程序(稍后讨论)使用,那么只有该应用程序应该能够看到其内容。但是,考虑到大量 Android 设备和 OS 版本(包括有根设备和自定义 ROM),我不会指望它。
您没有在 Intent
extras 中指定要传递的敏感数据类型,因此我只能给出这些一般性建议:
- 确保您了解相关数据的 "confidentiality level":它是秘密的,还是只是受限的?或者,也许是 public(在这种情况下不需要保护)?
- 尝试在
Intent
中寻找另一种不涉及传递敏感数据的方法(我自己从未遇到过这种需求)。 - 如果您绝对必须在
Intent
extras 中传递敏感数据 - 请考虑对其进行加密。加密模型应该足以 "confidentiality level" 的数据,以及如果数据被拦截可能造成的潜在危害(它可以一直达到 "server side" 加密)。
Privacy/security 与 BroadcastReceiver
一般来说,BroadcastReceiver
是一个接收"system wide"广播的组件。广播 "system wide" 本身应该说明与之相关的隐私级别。
也就是说,开发人员可以通过一种机制来限制广播的范围:自定义权限。使用自定义权限允许两个 "levels of control" 广播:
- 如果广播需要特定权限,那么只有
BroadcastReceiver
拥有该权限才能接收广播。 - 如果
BroadcastReceiver
通过特定权限过滤传入的广播,则只有带有该权限的广播才会传送到该接收者。
虽然以上几点乍一看很相似,但这些都是可以单独使用或组合使用的不同方案。第一种方案将广播与权限相关联(并且该广播的发送者自己不一定具有该权限),而第二种方案通过特定权限过滤所有广播(并且接收者必须具有该权限)。
您的情况更好的方法
编辑: 如果 "wakefullness" 不是要求的一部分,这可能是一个更好的方法。但它是。由于无法保证由 AlarmManager
启动的 Service
将有机会获得唤醒锁 - 这种方法不适合 OP 的情况。
请注意,广播和自定义权限的设计是为了在应用程序级别引入 "decoupling" - 这种方案允许发送方应用程序完全不知道接收方应用程序,只要他们同意一个自定义许可(好吧,同样的方案也适用于 pre-installed public 许可,但您不希望使用 public 许可来保护您的敏感数据)。
但是,在您的情况下,发送方和接收方是同一个应用程序。在这样的设置中,您真的不需要与广播相关的所有麻烦 - 只需构造 PendingIntent
即可在您的应用程序中启动所需的 Service
,您可以立即获得所有内容:
PendingIntent
和关联的Intent
在您的应用程序中启动一个特定的Service
(按名称),因此没有其他应用程序可以拦截它(理论上,请记住上面的讨论)。- 目标
Service
可以是 non-exported,因此其他应用程序无法以任何方式访问它。
欢迎您:)