I have spent the last few days getting an OAuth implementation up and running. Not on Android, but on my web server that will act as the proxy to the OAuth protected service. I'm just about to implement my Android client and my head is still churning over security and implementation issues.
OAuth is messy enough when the client is just a web browser. You have the following series of steps:
Now that's quite enough as it is. But when using the same mechanics with a mobile app as a client it gets even more involved. The problem is of course that you have to do some acrobatics to inject a browser session into your mobile app's code flow while doing the OAuth dance. This means you have to further complicate the OAuth dance as follows (I am using an Android app for this example to make things concrete):
This is rather hideous as you can see. If there is a much simpler way of doing this then I am eager to hear it. As far as I know there only two other alternatives, each with their own significant problems.
1) Forget about a proxy server and do everything directly from the mobile web app. The big security hole here is that you have to "bake" in your OAuth consumer key and secret into your app. If an attacker decompiles your code and hunts down those strings, a fairly easy operation for someone who is experienced at reverse engineering, they can wreak havoc with your application and users.
2) Switch to XAuth where the user provides you with their login name and password, and you "agree" not to store them and exchange them directly for an access token with the XAuth server. The first problem is gaining user trust to provide that information, the problem OAuth was created to solve, and of course what about people that don't honor their commitment to discard the login details? Worse, the XAuth server must support XAuth and offer HTTPS (SSL) connections and I have seen tons of web API's that don't support either. An SSL connection is necessary of course because without it you'd send the user's login name and password over the wire in plain text when making your XAuth request.
http://blog.zyber17.com/post/1283741364/why-xauth-is-a-really-dumb-idea
FYI, although it does not use a proxy server the following example illustrates the technique I described above for injecting a browser session into your mobile app OAuth interaction and intercepting the callback URI:
http://blog.doityourselfandroid.com/2010/11/10/oauth-flow-in-android-app/
So it seems pretty ugly any way you look at it and I didn't even get into the additional annoyance of creating and managing your own user ID for the user so you can look up their access tokens stored on your proxy web server properly (including the messiness of one more PIN or access code for the user to manage).
Interesting side note: When doing some research on an Android web browser session security I was pleased to find out that you are not allowed access to the current web page HTML. If you could access it, then a hostile Android coder could easily sniff out the user's login and password thereby defeating the purpose and intent of OAuth entirely. I was dismayed to find out that there may be a way to get that HTML by way of the CacheManager object. Curiously enough that object is now deprecated and schedule for removal according to the Android docs so hopefully that means Google discovered the (potential) security hole and is taking steps to remove it in an upcoming build:
http://developer.android.com/reference/android/webkit/CacheManager.html
In closing, I'd like to hear the thoughts of those out there that have struggled with these very same issues when creating their OAuth applications.
-- roschler
Janrain has released a library which provides some UI glue and a proxy backend login system; it supports a bunch of popular OAuth identity providers (e.g. Google/FB). At the end of the sign in flow you get an HTTPS POST from the device supplying you with a token exchangeable for a user identifier and other info, and a channel to return an access token to the device.
http://www.janrain.com/products/engage/mobile
https://github.com/janrain/engage.android
Disclosure: I work at Janrain, on this library.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With