The OAuth / App Anti-Pattern


OAuth was designed to combat an anti-pattern.

Typing your username and password into a third party site is bad idea. A really bad idea. I mean, you may think it's a bad idea to give your bank details to a Nigerian prince but that's just peanuts compared to giving away your password to an untrusted site!

So, that's why we use OAuth. Rather than handing details to a random site, we authenticate against a trusted site which then redirects us back with an authentication token.

That's all well and good on the web, but on mobile apps it becomes a little more difficult.

This is the popular mobile game Temple Run. After dying in the game (as I frequently do!) you can Tweet your score. But, first, you need to connect with Twitter. Temple Run Twitter

However, clicking the button, presents this screen: Temple Run Twitter OAuth This is a pop-up within the game. What you see in the screenshot is the totality of what the user sees.

There are now two important questions:

  1. How can the user tell if this is the genuine Twitter site?
  2. Why is there no indication that the site is served over HTTPS?

This is a clear anti-pattern! We're teaching people to give over their usernames and passwords to sites that appear to be genuine - yet offer no way to validate their legitimacy.

We've been trying to educate people to look at the URL bar - to check that they've visited the correct site and that there's some form of SSL verification (commonly a padlock).

I'm not suggesting that Temple Run is doing anything other than pointing to the correct site. Just that they aren't giving the user a chance to verify the authenticity.

How To Solve This Problem

I haven't the foggiest! Thoughts?

We can't rely on the user having the Twitter app installed and firing via intent (or similar). Due to the huge variety of phones and Operating Systems, there's no easy way (that I know of) to redirect from a website back to the app. There needs to be a way to keep everything in-app to keep the user experience.

So, come on then oh great minds of the Internet, how do we fix this?


Share this post on…

  • Mastodon
  • Facebook
  • LinkedIn
  • BlueSky
  • Threads
  • Reddit
  • HackerNews
  • Lobsters
  • WhatsApp
  • Telegram

13 thoughts on “The OAuth / App Anti-Pattern”

  1. Though not a direct solution to showing the user the URL and SSL status, one way to prove authenticity would be if OAuth providers allowed users to set a secret word or phrase that is shown to them once they've provided their username but before they enter a password - as in some 3DSecure implementations - so the user knows to look for that before completing signin. Although again in an app that would be fairly easy to intercept without the user's knowledge.

    Otherwise, the only thing I can think of is a native OAuth implementation on each platform (like the Windows User Account Control overlay pop-up) that apps can/must call as a trusted intermediary rather than handling the process directly.

    Reply
  2. says:

    As I tweeted, it's the same with Draw Something and Facebook, a popup within the app with no signs of the url. I was under the impression that at least with twitter you could send people to the oAuth page via their default browser and then get twitter to return them to a url which the app can capture via an intent eg http://templerun.com/androidauth or templerun://signedin but as I've not bother to get past page one in Android Coding 101 I couldn't confirm.

    Reply
  3. Paul Todd says:

    Maybe the the oauth provider (fb other twitter) could txt a code to the registered mobile on the service that could be used instead

    Reply
    1. says:

      True - but not every device can receive SMS. An email may be better. But, again, not every device can receive email. I think that it needs to be self contained.

      Reply
  4. says:

    If only we had some kind of browser that could open, with a standard set of chrome to indicate the URL and the HTTPS status.

    Oh wait, the UX people will object. Because security is so much less important than UX. Silly me. I keep forgetting.

    Reply
  5. Daniel Appelquist says:

    Indeed, this is the elephant in the Oauth room (at least when it comes to mobile). It's not just limited to apps, either, because in many mobile browsers (notably ios) its not possible to verify the authenticity of the certificate used to secure the https session. On desktop browsers, you can click on the lock icon and see some indication that, yes, this is actually my bank I am talking to. Not so on mobile browsers. And as you rightly point out, when this session is happening in a Web view in an App, all bets are off. The page could be from anywhere and there's no way for the user to know if it's secure or not, let alone validate the certificate.

    I think we need a standard "chrome" for these chromeless web views that can reliably display security information, including allowing the user to drill down to view information on the certificate.

    Is this something being discussed in the w3c coremob community group? http://www.w3.org/community/coremob/ If not, it should be. Paging @jamespearce.

    Reply
    1. says:

      Interesting. I know on Android, you can see the padlock (and check the cert if you want).

      The issue on a chromeless web views is that a malicious app could fake the chrome.

      Reply
  6. says:

    Andrew is correct that the conventional way to address this problem is to present the user with something that malicious code trying to impersonate the legitimate server cannot know (e.g. Yahoo's sign-in-seal, 3D-Secure's "personal assurance message").

    There is a specific problem on mobile devices though, due to the inability for the user to distinguish between a browser instance and a malicious app: the app can create a pixel-perfect image of a browser window by writing to the full screen, connect to the legitimate site using its own HTTP(S) code, and become an undetectable man-in-the-middle.

    To get round that, the secret sign must not be held on and delivered by the server, it must be in a trusted app on the phone which takes over the screen, shows the secret sign to the user, handles the OAuth exchanges, and then returns the token to the untrusted app. I proposed this in my talk at OTA last year (slide 18).

    Reply
  7. says:

    Furthermore, there's a couple of other problems with oauth: 1. If the web view is embedded, there are delegate callbacks available to the developer. This means it's trivial for the developer to intercept and examine the request; I.e. read the credentials; embedded web views essentially dont provide what they are attempting to do 2. Every oauth enabled app has a concept of their app key - this is why the provider can say "Application x wants your permission to log in" (and obviously, identify the application for security reasons). When your app is web based, you can secure you app key relatively easily (by encryption, local file permissions, etc.). If you're on mobile, it needs to be embedded in you app (I.e. every copy of your app). You can obfuscate it, but it is very difficult to actually secure it.

    The first problem is one of user education (never gonna happen), whilst the latter requires operating system capabilities to do right.

    Incidentally, both iOS and android support URL handling mechanisms to launch apps, so natively jumping out to the browser for oauth does actually work. It is a terrible user experience though

    Reply
  8. says:

    You are really asking the wrong question 🙂

    OAuth isn't primarily used for protecting the user, but for protecting the service provider (access to the API.)

    OAuth is actually making the situation worse by fooling users that their "password" is secure.

    Users might be tempted to use the same password for multiple services - because a password is "secure" - and that's basically a bad idea.

    If you really want to improve the security, just use a separate password for API / 3rd party access. Make sure that this API access password is different from the normal login password. An age old technique ...

    If you need to keep the manageability of the API, combine it with xAuth or OAuth.

    This will make passwords more secure and the login process for 3rd party apps more seamless (when using xAuth) - and even offer access for non-browser devices (home appliances, whatever.)

    The most important thing is to use as many passwords as possible and to encourage users and support them to do so.

    Using the same password for Twitter, Facebook, GMail and the Playstation Network and maybe even your banking site might have horrible consequences :-}

    Reply
  9. says:

    The solution to this has been built into the spec since day one. The "correct" approach is to send the user to the website of the OAuth provider, using the default "http" handler on the device (i.e., the user's browser).

    The OAuth provider should then display a mobile-friendly sign-in / authorise page within the browser so that the user can authorise the application's request.

    Once they've clicked the authorise button, the OAuth provider should redirect back to the app using a custom protocol handler (e.g., x-templerun://authorize) that the app can register on the device. Once the app receives the redirect, it's able to obtain the token for future requests.

    It's a shame that Twitter et. al. haven't done a better job documenting this (or maybe they have?), because it really is supported in the design of the protocol. Native-app clients (desktop originally, not on the phone, since iPhone/Android apps didn't yet exist) were one of the motivating use-cases for OAuth.

    Reply
  10. says:

    One area where Android clearly outdoes iOS is in this very regard:

    http://developer.android.com/reference/android/accounts/AccountManager.html

    Apps, such as Twitter, Dropbox, Endomondo, Microsoft Exchange and formerly Facebook, can register account types and authenticator modules with the operating system. The OS can then provide a standardized interface to the user when an app requests account access. The user provides their password once, and any app that needs access gets it from the OS, rather than the website.

    This is a simple and elegant solution that protects the user.

    Unfortunately, due to the popularity of iOS, most Android developers aren't aware of these options, or for some reason simply choose not to use them. If iOS could get on board with a similar approach, we could really make some progress in terms of mobile security.

    One flaw of this approach is that it requires the app for the service to be installed, but I think this is an acceptable sacrifice, the question is how to implement a graceful fallback.

    Reply

What are your reckons?

All comments are moderated and may not be published immediately. Your email address will not be published.

Allowed HTML: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong> <p> <pre> <br> <img src="" alt="" title="" srcset="">