1

I scanned a project using Fortify and it says I should replace checkCallingOrSelfPermission method with checkCallingPermission.

I could not figure out the security risk that checkCallingOrSelfPermission method presents.

This is the Fortify explanation:

The function checkCallingOrSelfPermission() or checkCallingOrSelfUriPermission() determine whether the calling program has the required permission to access a certain service or a given URI. However, these functions should be used with care as they can grant access to malicious applications, lacking the appropriate permissions, by assuming your applications permissions.

This means a malicious application, without appropriate permissions, can bypass its permission check by using your application's permission to get access to otherwise denied resources. This can result in what is known as the confused deputy attack.

2 Answers 2

4

The confused deputy is when you are operating on behalf of another program, but you do not appropriately check permissions. The normal example of this is a grocery store cashier, scanning items using a barcode. If a malicious customer changes the barcode, for instance putting a carrot barcode on filet mignon, and the cashier simply scans and charges carrot prices, he/she is being a confused deputy. (On the other hand, if he/she notices, she's applying appropriate checking and is not a confused deputy, but a competent one)

In this case, what Fortify is saying is that you are being willing to substitute your own permissions for the caller's permissions (that's what checkCallingOrSelfPermissions does) - you are saying it doesn't matter what the caller can do, go with what you can do.

It is possible this is what you want - if your program is intended to perform privileged commands on behalf of unprivileged programs, this may be what you want. If that is that case, however, you are responsible for ensuring that the caller IS the real caller and that it isn't doing anything malicious. Fortify can't help you there - that is where you'd do a real, intense code inspection and some serious testing to make sure that that trust-boundary cannot be exploited by anything malicious. If your code passes, you'd normally then annotate so Fortify ignores it. These are called trust-boundaries and they are where you want to spend a lot of analysis time to make sure that you are performing appropriate controls.

You probably want to just listen to Fortify here and make the change, unless you've done the work to verify your inputs and are positive that this call cannot be used to do something malicious AND it is the only way to do something useful.

4

Imagine two apps: Alice and Bob. And, for the sake of argument, pretend the device only has those two apps on it.

If Bob calls checkCallingPermission(), Bob is asking "can Alice do this?"

If Bob calls checkCallingOrSelfPermission(), Bob is asking "can Alice or I do this?", which is an unusual question. Normally we are using these methods to secure apps against unwanted requests from third parties, and what permissions our apps hold do not matter for that particular situation.

It is possible that checkCallingOrSelfPermission() really is what you want. IMHO, there are fewer use cases for that, and so it's worth a scanner warning to suggest that perhaps you used the wrong method. Or, better yet, get rid of both methods and use android:permission attributes in the manifest, if your use case is fairly simple, as that automatically defends your components based upon the named permission.

1
  • "what permissions our apps hold do not matter for that particular situation" - I don't think this is true. If Bob does not have permission to access location e.g. I don't think Alice can request location via Bob, it doesn't matter if Alice has the permission. Also I am looking for a way to do this :)
    – rOrlig
    Commented Jan 3, 2020 at 5:36

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .