7

In view of the security model in Android, I'm trying to use custom permissions with a broadcast receiver.

WHAT I'VE DONE :

I have declared a custom permission for the receiver, thereby limiting the broadcasts that it can receive. Some code from manifest:

<permission android:name="abc"/>

<receiver android:name=".UpdateUserReceiver"
        android:permission="abc"
        android:enabled="true"
        android:exported="false">

        <intent-filter>
            <action android:name="android.intent.action.ACTION_UPDATE_USERNAME"/>
            <category android:name="android.intent.category.DEFAULT"/>
        </intent-filter>
</receiver>

Now I expect that receiver UpdateUserReceiver will only receive broadcasts from components which use the permission 'abc'.

Broadcast sending code:

// Update username. Invoke broadcast.
Intent updateUserBroadcast = new Intent();
updateUserBroadcast.putExtra("username", userName);
updateUserBroadcast.setAction("android.intent.action.ACTION_UPDATE_USERNAME");
sendBroadcast(updateUserBroadcast);

Activity which sends broadcast :

<activity android:name=".UpdateUserNameActivity">

        <intent-filter>
            <action android:name="com.intent.action.UPDATE_USERNAME"/>
            <category android:name="android.intent.category.DEFAULT"/>
        </intent-filter>
</activity>

Question 1 : As seen, the activity nowhere uses the permission which the receiver has declared, so that it can receive the broadcast from the activity. But still the receiver is invoked, and I suspect it's due to the use of implicit intents though I'm not sure. Any ideas?

Question 2 : What's the difference between the permission tag declared at app level, and android:permission tag inside the receiver? I understand the use of 2nd one, which enforces a permission before anyone can expect the receiver to receive the broadcast, but then why's the first one required. Is it needed for this scenario, or can it be removed. Either way, I have checked that the receiver receives the broadcast.

gaurav jain
  • 3,119
  • 3
  • 31
  • 48
  • minSdkVersion is 19, targetSdkVersion is 23, I'm targeting an x86 Kitkat Android emulator. – gaurav jain Dec 10 '15 at 12:48
  • as per my understanding, android system will verify whether the receiver has the permission to receive the broadcast. But in your case you are expecting it to work the other way and that is the reason i think your receiver is getting executed. – siva Dec 11 '15 at 13:51
  • if you want to execute your receiver only when trusted applications send the broadcast, then you can go for targeted broadcast. If this is what you are looking for let me know, i will give you more info. – siva Dec 11 '15 at 13:53
  • @7383, Regarding your comment 1, if I remove the outer permission, and just keep the one which is inside the receiver, then the broadcaster must have that permission in order to send broadcasts to this receiver. But still the activity is able to send broadcasts to this receiver without holding the permission. Check this link : http://developer.android.com/guide/topics/manifest/receiver-element.html – gaurav jain Dec 11 '15 at 13:58
  • @7383, Regarding comment 2, this is not a usual scenario that you'd encounter, because here my activity and receiver are in the same application. I just want to confirm that whether the permission model for Android works only in case of separate applications only. Also, I won't mind you sharing info regarding targeted broadcasts. Thanks. – gaurav jain Dec 11 '15 at 14:00
  • Ok got your point. you might be sending the broadcast from the same application. Have you tried sending the broadcast from different app? Look at this code. There is a PID check if calling PID is MY_PID then permission will be granted by default. http://androidxref.com/4.4.4_r1/xref/frameworks/base/services/java/com/android/server/am/ActivityManagerService.java#5696 – siva Dec 11 '15 at 14:33

3 Answers3

3

Answer 1:
the <uses-permission> tag in <manifest> requests a permission for all component in this application, you don't need to request a permission for a single activity. And The application declares the custom permission use <permission> will automaticall holds it, no necessary to request it again.
I guess your activity and the receiver are in the same application.
"implicit intents" can not break the "permission rule".

Answer 2:
the <permission> in <application> will set a permission that applies to all of the application's components.
check here: http://developer.android.com/guide/topics/manifest/application-element.html#prmsn

Swing
  • 858
  • 1
  • 8
  • 21
  • Thanks for the response, though I'm sorry your answer is somewhat misdirected from the question. For the first part, you said 'implicit intents" can not break the "permission rule"'. If that's the case, why is the activity able to break through and get to the receiver. Also, I haven't used anywhere so the application nowhere has permission to send broadcasts to the receiver. Yes, my activity and receiver are in the same application. Your answer 2 seems correct to me, so +1 for that. – gaurav jain Dec 07 '15 at 07:07
  • @gauravjain May be my suck English didn't make myself clear to you, please read this sentence in Answer 1 again: The application declares the permission will automaticall holds it, no necessary to request it again. – Swing Dec 08 '15 at 01:02
  • Hi Swing, I understand what you're trying to say. If so is the case, it means permission model would only work for separate apps. I know the above mentioned scenario is a bit unusual, and might not occur in practice, but I'd like you to quote some references which validate your statement. Thanks. – gaurav jain Dec 10 '15 at 13:02
  • As an experiment, I removed the tag from the root node in the manifest, so that it's only defined in the receiver. Then also I see same behavior. It might be due to the fact that Android created permission model for IPC between different applications only, and not within components in same application, but I don't see it mentioned in the documentation. – gaurav jain Dec 10 '15 at 13:18
2

But still the receiver is invoked, and I suspect it's due to the use of implicit intents though I'm not sure

No.

Any ideas?

They are both in the same app ("because here my activity and receiver are in the same application"). Permissions are applied between apps, as part of inter-process communication (IPC), not within an app.

What's the difference between the permission tag declared at app level, and android:permission tag inside the receiver?

<permission> defines the permission. android:permission applies the permission. To draw a Java analogy, <permission> defines a field, android:permission uses the field.

CommonsWare
  • 986,068
  • 189
  • 2,389
  • 2,491
1

Ok got your point. you might be sending the broadcast from the same application. Have you tried sending the broadcast from different app? Look at this code. There is a PID check if calling PID is same app then permission will be granted by default. Hence your receiver is getting executed with out any problem. http://androidxref.com/4.4.4_r1/xref/frameworks/base/core/java/android/app/ActivityManager.java#2109

siva
  • 1,850
  • 13
  • 14
  • Though your answer seems correct, I will verify the behavior with different apps, and will award the bounty as soon as it's completed. Thanks. – gaurav jain Dec 11 '15 at 14:41
  • Agreed. if you refer the above link, code is written that way. Thanks. – siva Dec 11 '15 at 14:43