September 2011 Archives

When creating a native mobile app, it is often necessary to call RESTful Web services securely using OAuth. To do this, the native app needs an Access Token (AT). There are various ways for the app to get such a token, each presenting certain pros and cons. Around the Web, you will find two primary suggestions on how to do this:

  1. From the native app, pop open a browser to the Authorization Server (AS) where the user will authenticate and authorize the native app to access their resources. Return the AT to the native app via a scheme registered with the mobile OS.
  2. Embed a Web browser control in the native app that renders the AS's Web pages inside it and get the AT as it goes by.
The problem with the first is that multiple applications can register for the same scheme, opening up the native app to phishing. The latter is a problem because the native app can see everything that goes by including the Resource Owner's (RO's) credentials. This is OK if you trust the app not to do that, but that isn't always the case and is reminiscent of the password anti-pattern that OAuth was designed to fix. For more details on these attacks, see this whitepaper (PDF).

At IIW this week, Personal's CTO, Tarik Kurspahic, organized a session to talk about how best to get OAuth tokens into native apps. In it, he, Scotty Logan of Stanford University, myself, and the other participants came up with the following alternative to the popular suggestions above which does not allow the installed app to see the RO's credentials and is not susceptible to phishing.

Here's a diagram showing what we came up w/.

oauth_mobile.gif

This is basically traditional 3-legged OAuth w/ a twist, but it's involved. So let me explain:

  1. The native app pops open the mobile phone's browser to a Web page that is developed and hosted by the same org that owns the native app. On the URL of this request is the registration ID of the app. This ID is unique to the app on a particular device and is provided by the Google or Apple notification service (see below).
  2. This Web page redirects the RO's Web browser to the AS. In the 302, it stores the registration ID in a cookie.
  3. The RO authenticates to the AS and grants the native app access their resources.
  4. The AS redirects the RO back to the helper page which is registered as the callback. On the query string of this request in the Access Code (AC) and the cookie w/ the registration ID is also sent.
  5. Rather than resolving this code for an AT as in a traditional Web server flow, it sends the AC as the payload to either Google's or Apple's notification service. To do this, the helper app needs to use an app-specific credential to authenticate to the notification service. By authenticating the call w/ this app-specific key and by providing the saved registration ID, only the right app on the right device will receive the AC.
  6. The notification service sends the message to the appropriate app on the appropriate mobile device.
  7. The app then sends the AC to the AS to get an AT.
  8. It can then use the AT to securely call the API.

After the session, I ran this by Paul Madsen, Brian Campbell, and others. No one found any issues w/ it, but, like some in the session, they wondered why such a complicated arrangement was needed. Till the folks on the Android team and at Apple provide secure IPC in their mobile OSes, I don't see any alternative unless you can make certain assumptions or are comfortable w/ the risks associated w/ the common alternatives. If you know a better way or see any security issues w/ this, please leave a comment below or drop me a line.

Thanks all for a great IIW and see ya in the spring!