一、前言
Public Broadcast Receiver可以接收所有广播,其风险是可以接收恶意软件的广播,注意事项
1、设置exported属性为true。
2、处理收到的intent,确认真实性和可用性。
3、返回结果时,注意不包含敏感信息。
二、原代码示例
1.PublicReceiver.java
package org.jssec.android.broadcast.publicreceiver;@b@ @b@import android.app.Activity;@b@import android.content.BroadcastReceiver;@b@import android.content.Context;@b@import android.content.Intent;@b@import android.widget.Toast;@b@ @b@public class PublicReceiver extends BroadcastReceiver {@b@ @b@ private static final String MY_BROADCAST_PUBLIC =@b@ "org.jssec.android.broadcast.MY_BROADCAST_PUBLIC";@b@ @b@ public boolean isDynamic = false;@b@ private String getName() {@b@ return isDynamic ? "Public Dynamic Broadcast Receiver" : "Public Static Broadcast Receiver";@b@ }@b@ @b@ @Override@b@ public void onReceive(Context context, Intent intent) {@b@ @b@ // *** POINT 2 *** Handle the received Intent carefully and securely.@b@ // Since this is a public broadcast receiver, the requesting application may be malware.@b@ // Omitted, since this is a sample. Please refer to "3.2 Handling Input Data Carefully and Securely."@b@ if (MY_BROADCAST_PUBLIC.equals(intent.getAction())) {@b@ String param = intent.getStringExtra("PARAM");@b@ Toast.makeText(context,@b@ String.format("%s:¥nReceived param: ¥"%s¥"", getName(), param),@b@ Toast.LENGTH_SHORT).show();@b@ }@b@ @b@ // *** POINT 3 *** When returning a result, do not include sensitive information.@b@ // Since this is a public broadcast receiver, the requesting application may be malware.@b@ // If no problem when the information is taken by malware, it can be returned as result.@b@ setResultCode(Activity.RESULT_OK);@b@ setResultData(String.format("Not Sensitive Info from %s", getName()));@b@ abortBroadcast();@b@ }@b@}
2.AndroidManifest.xml配置
<?xml version="1.0" encoding="utf-8"?>@b@<manifest xmlns:android="http://schemas.android.com/apk/res/android"@b@ package="org.jssec.android.broadcast.publicreceiver" >@b@ @b@ <application@b@ android:icon="@drawable/ic_launcher"@b@ android:label="@string/app_name"@b@ android:allowBackup="false" >@b@ @b@ <!-- Public Static Broadcast Receiver -->@b@ <!-- *** POINT 1 *** Explicitly set the exported attribute to true. -->@b@ <receiver@b@ android:name=".PublicReceiver"@b@ android:exported="true" >@b@ <intent-filter>@b@ <action android:name="org.jssec.android.broadcast.MY_BROADCAST_PUBLIC" />@b@ </intent-filter>@b@ </receiver>@b@ @b@ <service@b@ android:name=".DynamicReceiverService"@b@ android:exported="false" />@b@ @b@ <activity@b@ android:name=".PublicReceiverActivity"@b@ android:label="@string/app_name"@b@ android:exported="true" >@b@ <intent-filter>@b@ <action android:name="android.intent.action.MAIN" />@b@ <category android:name="android.intent.category.LAUNCHER" />@b@ </intent-filter>@b@ </activity>@b@ </application>@b@</manifest>
3.DynamicReceiverService.java
package org.jssec.android.broadcast.publicreceiver;@b@ @b@import android.app.Service;@b@import android.content.Intent;@b@import android.content.IntentFilter;@b@import android.os.IBinder;@b@import android.widget.Toast;@b@ @b@public class DynamicReceiverService extends Service {@b@ private static final String MY_BROADCAST_PUBLIC = "org.jssec.android.broadcast.MY_BROADCAST_PUBLIC";@b@ @b@ private PublicReceiver mReceiver;@b@ @b@ @Override@b@ public IBinder onBind(Intent intent) {@b@ return null;@b@ }@b@ @b@ @Override@b@ public void onCreate() {@b@ super.onCreate();@b@ @b@ // Register Public Dynamic Broadcast Receiver.@b@ mReceiver = new PublicReceiver();@b@ mReceiver.isDynamic = true;@b@ IntentFilter filter = new IntentFilter();@b@ filter.addAction(MY_BROADCAST_PUBLIC);@b@ filter.setPriority(1); // Prioritize Dynamic Broadcast Receiver, rather than Static Broadcast Receiver. registerReceiver(mReceiver, filter);@b@ Toast.makeText(this,"Registered Dynamic Broadcast Receiver.", Toast.LENGTH_SHORT).show();@b@ }@b@ @b@ @Override@b@ public void onDestroy() {@b@ super.onDestroy();@b@ @b@ // Unregister Public Dynamic Broadcast Receiver.@b@ unregisterReceiver(mReceiver);@b@ mReceiver = null;@b@ Toast.makeText(this,"Unregistered Dynamic Broadcast Receiver.", Toast.LENGTH_SHORT).show();@b@ }@b@}
4.PublicReceiverActivity.java
package org.jssec.android.broadcast.publicreceiver;@b@ @b@import android.app.Activity;@b@import android.content.Intent;@b@import android.os.Bundle;@b@import android.view.View;@b@ @b@public class PublicReceiverActivity extends Activity {@b@ @b@ @Override@b@ protected void onCreate(Bundle savedInstanceState) {@b@ super.onCreate(savedInstanceState);@b@ setContentView(R.layout.main);@b@ }@b@ @b@ public void onRegisterReceiverClick(View view) {@b@ Intent intent = new Intent(this, DynamicReceiverService.class);@b@ startService(intent);@b@ }@b@ public void onUnregisterReceiverClick(View view) {@b@ Intent intent = new Intent(this, DynamicReceiverService.class);@b@ stopService(intent);@b@ }@b@}
5.安全发送PublicSenderActivity.java - 不要发送敏感信息、接收数据的时候注意数据的真实性。
package org.jssec.android.broadcast.publicsender;@b@ @b@import android.app.Activity;@b@import android.content.BroadcastReceiver;@b@import android.content.Context;@b@import android.content.Intent;@b@import android.os.Bundle;@b@import android.view.View;@b@import android.widget.TextView;@b@ @b@public class PublicSenderActivity extends Activity {@b@ @b@ private static final String MY_BROADCAST_PUBLIC = "org.jssec.android.broadcast.MY_BROADCAST_PUBLIC";@b@ @b@ public void onSendNormalClick(View view) {@b@ // *** POINT 4 *** Do not send sensitive information.@b@ Intent intent = new Intent(MY_BROADCAST_PUBLIC);@b@ intent.putExtra("PARAM", "Not Sensitive Info from Sender");@b@ sendBroadcast(intent);@b@ }@b@ @b@ public void onSendOrderedClick(View view) {@b@ // *** POINT 4 *** Do not send sensitive information.@b@ Intent intent = new Intent(MY_BROADCAST_PUBLIC);@b@ intent.putExtra("PARAM", "Not Sensitive Info from Sender");@b@ sendOrderedBroadcast(intent, null, mResultReceiver, null, 0, null, null);@b@ }@b@ @b@ public void onSendStickyClick(View view) {@b@ // *** POINT 4 *** Do not send sensitive information.@b@ Intent intent = new Intent(MY_BROADCAST_PUBLIC);@b@ intent.putExtra("PARAM", "Not Sensitive Info from Sender");@b@ //sendStickyBroadcast is deprecated at API Level 21@b@ sendStickyBroadcast(intent);@b@ }@b@ @b@ public void onSendStickyOrderedClick(View view) {@b@ // *** POINT 4 *** Do not send sensitive information.@b@ Intent intent = new Intent(MY_BROADCAST_PUBLIC);@b@ intent.putExtra("PARAM", "Not Sensitive Info from Sender");@b@ //sendStickyOrderedBroadcast is deprecated at API Level 21@b@ sendStickyOrderedBroadcast(intent, mResultReceiver, null, 0, null, null);@b@ }@b@ @b@ public void onRemoveStickyClick(View view) {@b@ Intent intent = new Intent(MY_BROADCAST_PUBLIC);@b@ //removeStickyBroadcast is deprecated at API Level 21@b@ removeStickyBroadcast(intent);@b@ }@b@ @b@ private BroadcastReceiver mResultReceiver = new BroadcastReceiver() {@b@ @Override@b@ public void onReceive(Context context, Intent intent) {@b@ // *** POINT 5 *** When receiving a result, handle the result data carefully and securely.@b@ // Omitted, since this is a sample. Please refer to "3.2 Handling Input Data Carefully and Securely."@b@ String data = getResultData();@b@ PublicSenderActivity.this.logLine(@b@ String.format("Received result: ¥"%s¥"", data));@b@ }@b@};@b@ @b@ private TextView mLogView;@b@ @b@ @Override@b@ public void onCreate(Bundle savedInstanceState) {@b@ super.onCreate(savedInstanceState);@b@ setContentView(R.layout.main);@b@ mLogView = (TextView)findViewById(R.id.logview);@b@ }@b@ @b@ private void logLine(String line) {@b@ mLogView.append(line);@b@ mLogView.append("¥n");@b@ }@b@}
三、安全代码示例
1、不要发送敏感信息。@b@2、接收数据的时候注意数据的真实性。
PublicSenderActivity.java@b@ @b@package org.jssec.android.broadcast.publicsender;@b@ @b@import android.app.Activity;@b@import android.content.BroadcastReceiver;@b@import android.content.Context;@b@import android.content.Intent;@b@import android.os.Bundle;@b@import android.view.View;@b@import android.widget.TextView;@b@ @b@public class PublicSenderActivity extends Activity {@b@ @b@ private static final String MY_BROADCAST_PUBLIC = "org.jssec.android.broadcast.MY_BROADCAST_PUBLIC";@b@ @b@ public void onSendNormalClick(View view) {@b@ // *** POINT 4 *** Do not send sensitive information.@b@ Intent intent = new Intent(MY_BROADCAST_PUBLIC);@b@ intent.putExtra("PARAM", "Not Sensitive Info from Sender");@b@ sendBroadcast(intent);@b@ }@b@ @b@ public void onSendOrderedClick(View view) {@b@ // *** POINT 4 *** Do not send sensitive information.@b@ Intent intent = new Intent(MY_BROADCAST_PUBLIC);@b@ intent.putExtra("PARAM", "Not Sensitive Info from Sender");@b@ sendOrderedBroadcast(intent, null, mResultReceiver, null, 0, null, null);@b@ }@b@ @b@ public void onSendStickyClick(View view) {@b@ // *** POINT 4 *** Do not send sensitive information.@b@ Intent intent = new Intent(MY_BROADCAST_PUBLIC);@b@ intent.putExtra("PARAM", "Not Sensitive Info from Sender");@b@ //sendStickyBroadcast is deprecated at API Level 21@b@ sendStickyBroadcast(intent);@b@ }@b@ @b@ public void onSendStickyOrderedClick(View view) {@b@ // *** POINT 4 *** Do not send sensitive information.@b@ Intent intent = new Intent(MY_BROADCAST_PUBLIC);@b@ intent.putExtra("PARAM", "Not Sensitive Info from Sender");@b@ //sendStickyOrderedBroadcast is deprecated at API Level 21@b@ sendStickyOrderedBroadcast(intent, mResultReceiver, null, 0, null, null);@b@ }@b@ @b@ public void onRemoveStickyClick(View view) {@b@ Intent intent = new Intent(MY_BROADCAST_PUBLIC);@b@ //removeStickyBroadcast is deprecated at API Level 21@b@ removeStickyBroadcast(intent);@b@ }@b@ @b@ private BroadcastReceiver mResultReceiver = new BroadcastReceiver() {@b@ @Override@b@ public void onReceive(Context context, Intent intent) {@b@ // *** POINT 5 *** When receiving a result, handle the result data carefully and securely.@b@ // Omitted, since this is a sample. Please refer to "3.2 Handling Input Data Carefully and Securely."@b@ String data = getResultData();@b@ PublicSenderActivity.this.logLine(@b@ String.format("Received result: ¥"%s¥"", data));@b@ }@b@};@b@ @b@ private TextView mLogView;@b@ @b@ @Override@b@ public void onCreate(Bundle savedInstanceState) {@b@ super.onCreate(savedInstanceState);@b@ setContentView(R.layout.main);@b@ mLogView = (TextView)findViewById(R.id.logview);@b@ }@b@ @b@ private void logLine(String line) {@b@ mLogView.append(line);@b@ mLogView.append("¥n");@b@ }@b@}