Permissions automatically added to android app manifest

Last week when I displayed a QR code to download my app, the one person who talked to me about it was a security person, and of course she asked: why does it need these permissions?

Storage: modify/delete SD card contents. Phone calls: read phone state and identity

Say what? I didn't ask for those!

Truth be told, I had no idea (except for the start-at-boot, which is in the manifest and needed so it can install alarms at boot). I noticed them when I did a test install but didn’t think much about it because I was in a hurry. No, LogMyLife doesn’t need to write to the SD card or read the phone identity. OK, it will need to write to SD once I implement export/import of data; but it will never need to read the phone identity.

Tonight I finally got a chance to look into this. It turns out, if you build your app to run on the 1.5 platform (which LogMyLife does so that my wife’s Cliq can use it), these permissions are silently added when the APK is created. Believe it or not this is “working as designed” according to this Google Code issue. Romain Guy could have been a little more helpful there and provided a link to some kind of useful explanation, but I get the drift: because these permissions were introduced in 1.6, they’re grandfathered in to apps built for previous versions (which didn’t have to declare them), and so have to be included for them to work on platforms 1.6 and up, just in case they’re needed.

There’s some kind of voodoo in the Android Market that keeps these added permissions from showing up at download/install time. But they’re still technically there, and they’ll show up if the user looks at the application permissions later. Also they’ll show up at install via non-Market path, like during beta testing. Sigh! Fortunately, or un-fortunately, most users are pretty oblivious to permissions. But not security people.

So, what to do? I could exclude my wife and the other unfortunates stuck on 1.5 and just target 1.6+. Perhaps I could provide different APKs, one just for 1.5, and another for 1.6+? Well, regardless of that, what I think every app author should be doing is explaining exactly what they’re doing with those permissions. I’ll include a section in the app README, and also in the Market description (once it’s on there), explaining what permissions are used and why, and I can explain where these two come from if needed.

Advertisements

Clustering Tomcat (part III): the HTTPS connector

Refer to my earlier posts on the subject for background. Here are further explorations, not having much to do with clustering as it turns out, but everything to do with proxying.

In a number of situations you might want to set up encrypted communication between the proxy and backend. For this, Tomcat supplies an HTTPS connector (as far as I know, the only way to encrypt requests to Tomcat).

Connector setup

Setup is actually fairly simple with just a few surprises. Mainly, the protocol setting on the connector remains “HTTP/1.1” not some version of “HTTPS” – the protocol being the language spoken, and SSL encryption being a layer on top of that which you specify with SSLProtocol. Basically, HTTPS connectors look like HTTP connectors with some extra SSL properties specifying the encryption:

<Connector executor="tomcatThreadPool"
 port="${https.port}"
 protocol="HTTP/1.1"
 connectionTimeout="20000"
 acceptCount="100"
 maxKeepAliveRequests="15"
 SSLEnabled="true"
 SSLProtocol="TLS"
 scheme="https"
 secure="true"
 keystorePass="changeit"
 clientAuth="false"
/>

If I really wanted to be thorough I would set clientAuth=”true” and set up the proxy with a client certificate signed by this server’s truststore, thereby guaranteeing only the proxy can even make a request. But not right now.

Note the “scheme” and “secure” properties here. These don’t actually affect the connection; instead, they specify what Tomcat should answer when a servlet asks questions about its request. Specifically, request.getScheme() is likely to be used to create self-referential URLs, while request.isSecure() is used to make several security-related decisions. Defaults are for a non-secure HTTP connector but they can be set to whatever makes sense in context – in fact, AFAICS the scheme can be set to anything and the connector will still serve data fine. Read on for clarity on uses of these properties. Continue reading