Blog

bevkjbvkbdkdxoeoziejdoiehz fiugebfuyegwik

NOAuth

We all know those pesky UIWebViews for logging into services like Facebook, Twitter or Dropbox on our mobile devices. They look crappy and are annoying, but they protect our passwords from those evil app developers, right?

Wrong. They are security theater, nothing more. And one of the worst kinds, because they give users the impression that they do not have to trust the individual app developer, but that's not the case.

Those of you with a technical background will probably mumble something about same origin policy, but that doesn't help here at all. Being a mobile app means being the browser and when you are the browser, you can do whatever you want, no questions asked.

There are different approaches for getting to the user's credentials, I will present the easiest here and I will concentrate on iOS:

  1. We register a custom NSURLProtocol for 'keylogger://' URLs. It is a dummy implementation which just makes sure that those URLs aren't processed further by the framework.

  2. In the webView:didFinishLoad: method, inject some JavaScript into the loaded page. The JavaScript will attach a listener to every input element on the page and that listener will call a 'keylogger://' URL crafted by us which contains the character the user entered.

  3. In the shouldStartLoadWithRequest: method, we capture all of the 'keylogger://' requests and log the characters. Then we stop loading, because those URLs are just used to communicate between JS and Objective-C.

That's it. The process is so basic that any iOS developer can add it to his app and there is nothing the user can do the prevent it, apart from not entering their passwords into apps they do not trust.

In terms of prior coverage of this, I only discovered this article, but I assume the issue is well-known and documented for a long time, but as there seems to be no simple demonstration of the problem, I created one. It is a slight modification of the SCFacebook example app which will present you an UIAlertView with the credentials you just entered when you logged in.

The FBConnect login dialog

The login dialog's layout is slightly off, but that can easily be fixed by improving the keylogger's JavaScript. Don't get me started on how crappy this page looks and how easy it is to recreate it for phishing purposes. Remember, the user cannot see the URL in an UIWebView, either.

UIAlertView with 'foo@example.com12password#' in it

The logged keys are stored in one string, but it's not that hard to separate the address from the rest.

So that's it, OAuth with UIWebViews doesn't add any security. Facebook and friends should stop using them today - a native login communicates that you have to trust the app with the credentials you are giving it, fooling users with security theater is not good. After that, we need a proper and secure way for protecting passwords from apps.