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.
However, clicking the button, presents this screen:
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:
How can the user tell if this is the genuine Twitter site?
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?
Why doesn't Twitter's OAuth let me specify the length of time a 3rd party has access to my account? Take a look at all the crap you've given access to your Twitter account. Are you ever going to use that "See how many of your friends like cheese" app again? No.
At the bottom is an "Access Duration" option - giving you the option to try out the app and have it automatically revoke after a specified period of time.
Now, this isn't something you'd want to do for every app. But it gives you a method to limit the damage that a malicious app can do. Remember, just because an app isn't malicious today, doesn't give you any guarantee about its future performance.
expires_in
OPTIONAL. The duration in seconds of the access token
lifetime. For example, the value "3600" denotes that the
access token will expire in one hour from the time the response
was generated.
If you run a service relying on OAuth, please consider giving users an Access Duration option.
I am no longer confused! Here is a quick tutorial in how to post images to Twitpic and Twitter when using OAuth. I'm indebted to Steve Corona of Twitpic, for his help with this.
Next, we create the OAuth credentials that we need. Essentially, we're signing a URL request. We then pass that on to Twitpic and they verify it with Twitter. We never pass our OAUTH_CONSUMER_SECRET - so Twitpic can't impersonate us.
The data we send to Twitpic (message text, image and key) have to go via POST.
//TwitPic requires the data to be sent as POST
$media_data=array(
'media'=>'@'.$_FILES['media']['tmp_name'],
'message'=>' '.stripslashes($_POST['message']),//A space is needed because twitpic b0rks if first char is an @
'key'=>TWITPIC_API_KEY
);
curl_setopt($ch, CURLOPT_POST,true);
curl_setopt($ch,CURLOPT_POSTFIELDS,$media_data);
All done, we now send the data to Twitpic.
//execute post
$result= curl_exec($ch);
$response_info=curl_getinfo($ch);
//close connection
curl_close($ch);
If this has worked, Twitpic will pass back the URL of the image we posted. We then need to post the entire message to Twitter ourselves (Twitpic can't do it for us).
if($response_info['http_code']==200)//Success
{
//Decode the response
$json= json_decode($result);
$id=$json->id;
$twitpicURL=$json->url;
$text=$json->text;
$message=trim($text)." ".$twitpicURL;
This next part is specific to Dabr - your client may post things differently.
Twitpic has implemented an OAuth API. No more having to hand out passwords to all and sundy. Only I'm too much of a dunderhead to get it working. Perhaps it's a combination of heatstroke or this rotten head-cold, but I just can't see what I'm doing wrong. Any help much appreciated.
I'm following the header example in the API documentation. Passing these variable to Twitpic is where I seem to go wrong.
$header = array(
'X-Auth-Service-Provider: https://api.twitter.com/1/account/verify_credentials.json',
'X-Verify-Credentials-Authorization: OAuth realm="http://api.twitter.com/"'
);
This morning, when I logged on to Twitter, I saw a user who I didn't recognise tweeting away in my timeline.
I wracked my brains thinking about how they could have gotten in there before I realised it was a long-dormant friend who had changed their name and avatar.
But, in thinking about how a spammer could infiltrate one's timeline, I think I came up with a fairly bullet-proof method to spam Twitter users.
I present this as an exercise in devious thinking - and also to show how our assumptions about security can play against us. Remember, hacking and impersonation are likely to be illegal in your jurisdiction. This information is designed to help you understand how security weaknesses can occur.
Being Evil
Imagine you are a nasty, evil Twitter spammer. Your own mother wouldn't spit on you if you were on fire - that's how mean you are. Here's what you do.
Obtain a user's password. Admittedly, this is the hardest part of the process. You might use a dictionary attack, use the same password they use to log in to another site, or somehow steal it.
Log on to Twitter.
Go to "Connections" and see which services they have connected to using OAuth. For the purposes of this experiment, let's assume they use Example.com.
Go to Example.com and OAuth yourself with Twitter using your mark's credentials.
Here's where the ordinary spammer falls down. The ordinary spammer will start sending out messages from the mark's account. That's not the aim of this weakness.
From the mark's account, through Example.com, make your victim follow one of your spam accounts. An account which exists solely to show adverts to your victim.
Your victim now sees your adverts for pills, poker and porn in their timeline. With any luck, they'll just assume that one of their true friends is promoting your illicit wares.
Counter Attack
Most victims will assume that they accidentally followed your spam account - or that one of their friends has been hacked.
Worst case scenario, they unfollow your spam account.
So you just make them follow you again! Remember, you are still OAuth'd to Example.com. You can make them follow as many of your spam accounts as you think you can get away with.
At this point, the intelligent victim will think that their account may be compromised and change their password.
It doesn't matter! Because you have used OAuth, password changes don't affect you. You can continue make them follow as many of your spam accounts as you think you can get away with.
At this point, the really intelligent victim will go through their OAuth connections to look for something suspicious. They won't find it. Remember steps 3 and 4? You are OAuth'd to a service that your victim trusts.
Because of the way Twitter displays OAuth information, there's no way for a victim to know when a service was last authorised.
Twitter OAuth Connections
There is no information other than the first time the OAuth was set up. No last accessed date, no IP addresses, nothing useful.
When following an account, the victim gets no notification of what has happened, when it has happened or how it has happened. There is no way of them knowing which of their OAuth'd connections have been compromised, nor when it happened.
Their only safe option is to revoke every single OAuth connection. Then reauthorise. A time consuming and annoying prospect.
Conclusion
I hope I've demonstrated two things.
Firstly, there's more to spam then just sending out messages. Forcing someone to read a message is just as annoying.
Secondly, our understanding of security and usability haven't quite caught up with the new tools which are available to us. OAuth is still better than giving your password to an untrusted site - but without essential usability changes, a compromised account is a lot more dangerous than the user would suspect.
This "attack" still relies on a victim having their original password compromised. That's not a trivial matter. But security is like sexual health - it only takes one little accident...