Vet Your Manifest

It should go without saying that you own what you ship to users. By this, I mean that you are responsible for what goes into the app, and you are responsible for the impacts that your app has on the device and on other apps that may be on that device.

Of course, we tend to think of this a lot, but in terms of code. We test our Java, Kotlin, C, C++, etc. We test our resources, sometimes directly, sometimes indirectly (by their impacts on the UI that we test).

But, what about the manifest?

Certainly, some aspects of it wind up being tested, such as whether we have enough <uses-permission> elements, for all of the secure APIs that we happen to call. But, what are you doing to ensure that your manifest contains what you expect it to contain: nothing more and nothing less?

For example, while writing this blog post, I noticed that Android Studio 3.0.1 (and the related tool chains) can generate duplicate <uses-permission> elements through the manifest merger process. In this case, adding LeakCanary gives your APK duplicate <uses-permission> elements for READ_EXTERNAL_STORAGE. This particular problem should be benign, but at best, we are wasting a bit of space. At worst, this causes problems with some future version of Android.

For larger apps, the problem with the manifest is that it can be this “wall of XML”, even before you start thinking about manifest merger. And to illustrate that, I’ll point you to one of the more bizarre problems I’ve seen on Stack Overflow:

A developer went to install his app on a particular device, and it failed to install, due to a duplicate permission error. On Android 5.0+, two apps cannot have the same <permission> element in the manifest, for the same name, unless both apps are signed by the same signing key. So, the developer’s app collided with an app that was already installed, both defining the same custom permission.

Except the custom permission was one that the developer had created for his own app… and the collision was with Samsung’s Bixby Voice app.

Bixby, as you’re probably aware, is Samsung’s AI agent. I’m sure that it’s nice, though I have never used it. Not only do I have grave concerns over this whole area (on privacy and security grounds), but I worry that if I make Bixby angry, it might turn into a giant green rage monster.

Bixby Voice has a lot of custom permissions in its manifest. All but one are in the com.samsung namespace, as you might expect for a Samsung proprietary app. Just this one permission lies outside that namespace.

So, why does Bixby need to define a custom permission matching one from a baseball card tracking app?

The leading theory: somebody copied and pasted some code out of another Stack Overflow question, where the developer had shown this custom permission as part of that question. That question has since been edited, to help prevent this sort of copy/paste issue in the future.

Copying and pasting from Stack Overflow is so common, it has been immortalized in book cover form. However, it is incumbent upon you to adapt that pasted material to local conventions… such as keeping custom permissions inside of your namespace.

In the end, this too is not a huge problem. Yes, it sucks for users of that baseball card tracking app. Yes, it sucks for that developer, who now needs to consider changing that custom permission (or perhaps just getting rid of it). In the grand scheme of things, though, this problem is not affecting lots of people.

But, you own what you ship.

The cruft in your manifest might be fine, or it might be a problem for some people, or it might wind up someday being a problem for a lot of people. It’s cruft, so get rid of it.

Modern tools make this comparatively easy. Use the “Merged Manifest” sub-tab of the manifest editor in Android Studio, to see what is going into the manifest from all sources. Double-check that with the APK Analyzer, to see the contents of the manifest in your production APK. Does everything in there need to be there? What can you get rid of that is no longer needed? What does not match the coding style rules for this project? And, for larger projects, can you automate these checks, so that nothing leaks into the merged manifest that is unexpected?

Vetting your manifest should be a part of the product release cycle, no different than all the other checks that you do to make sure that your app is “ready for prime time”. Just because it’s not executable code does not mean that you can ignore it.

NOTE: No actual giant green rage monsters were harmed in the creation of this blog post.