I'm making a twitter client, and I'm evaluating the various ways of protecting the user's login information.
IMPORTANT: I need to protect the user's data from other other applications. For example imagine what happens if a bot starts going around stealing Twhirl passwords or Hotmail/GMail/Yahoo/Paypal from applications that run on the user's desktop.
Clarification: I asked this before without the 'important' portion but stackoverflow's UI doesn't help with adding details later inside the Q/A conversation.
Any ideas ?
This is a catch-22. Either you make the user type in his password every time, or you store it insecurely (obfuscated, encrypted, whatever).
The way to fix this is for more operating systems to incorporate built-in password managers - like OS X's Keychain. That way you just store your password in the Keychain, the OS keeps it secure, and the user only has to type in 1 master password. Lots of applications (like Skype) on OS X use Keychain to do exactly what you are describing.
But since you are probably using Windows, I'd say just go with some obfuscation and encryption. I think you may be slightly paranoid about the password-stealing-bots; if your application doesn't have a large userbase, odds are pretty low that someone will target it and specifically try to steal the passwords. Besides that, they would also have to have access to their victim's filesystem. If that's the case, they probably have a virus/worm and have bigger problems.
I think you are missing the bigger picture here:
If the desktop is compromised, you're F#*%ED!
To steal a password from your program, a virus would have to be running on the system as administrator. If the virus has achieved that, stealing passwords from your program is way down on it's list of malicious things it wants to do.
Store it in plain text and let the user know.
That way, there are no misconceptions about what level of security you have achieved. If users start complaining, consider xor'ing a published-on-your-website constant onto it. If users keep complaining, "hide" the constant in your code and tell them it's bad security.
If users can't keep bad people out of the box, then in effect all secret data they have is known to Dr. Evil. Doesn't matter whether it's encrypted or not. And if they can keep evil people out, why worry about storing passwords in plain text?
I could be talking out my ass here, of course. Is there a study showing that storing passwords in plain text results in worse security than storing them obfuscated?
If you are making a twitter client then use their API
Twitter has very good documentation, so I advise you read it all before making a client. The most important part in relation to this question is that you don't need to store the passwords, store the OAuth token instead. You need to use the xAuth stage to get the OAuth token, then use other Twitter API's with this OAuth token where necessary.
xAuth provides a way for desktop and mobile applications to exchange a username and password for an OAuth access token. Once the access token is retrieved, xAuth-enabled developers should dispose of the login and password corresponding to the user.
You never store passwords if you can get away with it
Using OAuth the worst that can happen is a 3rd party (black hat hacker) gets access to that Twitter account but not the password. This will protect users which naively use the same password for multiple on-line services.
Use a keychain of some sort
Finally I agree that pre-made solutions such as OSX's keychain should be used to store the sensitive OAuth information, a compromised machine would only reveal the information of the currently unlocked keychains. This means in a multi user system only the logged in users have their keychains become vulnerable.
Other damage limitations
There may be stuff that I've missed take a Google for "best security practices" and start reading for what may be relevant.
EDIT (in response to finnw desired general case solution)
You want, given no user input, access to an on-line service. This means typically you have, at most, user level access control to the authentication credentials via something like Keychain.
I have never used OSX Keychain so now I'll talk about SELinux. In SELinux you can also ensure these authentication credentials would only given to your program. And if we are continue going on OS level stuff, you could also sign all processes from boot to cryptographicly be certain no other program could be mimicking your program. This is all beyond a typical user system and given this level of setup you can be assured the user is not naive enough to be compromised, or a sysadmin is compitant enough. At this level we could protect those credentials.
Lets assume we don't go that far into protecting those credentials, then we can assume the system is compromised. At this point the authentication credentials become compromised, obfuscation/encryption of these credentials on the local side don't add any real security and neither does storing part or all of it on a 3rd party server. This is easy to see because given no user input, your program needs to bootstrap itself to obtain those credentials. If your program can do it with no input, then so can anyone who has reversed engineered your obfuscation/encryption/server protocol.
At this point it is damage limitation, don't store the password as authentication credentials. Use OAuth, cookie sessions, salted hashs, etc, they are all just tokens representing that at some point in the past you proved you knew the password. In any good system these tokens can be revoked, time expired and/or periodical exchanged for a new token during active session.
The token (whatever form it may be) can also contain additional non user input authentication information which restricts your ability to use them elsewhere. It could for example encapsulate your hostname and/or IP address. This makes it difficult to use the credentials on a different machines since mimicking these forms of credentials would require access to the appropriate level of network infrastructure.
Upon further contemplation I think I found a way. I will use ASP.net authentication for my application desktop application, store their credentials online and let Internet Explorer's password manager handle the local caching of this secondary pair or credentials for me.
I will just have to have them authenticate through a Facebook-API like form during the first login.
I don't get it... why is encryption no good? Use a large key and store the key in the machine key store (assuming Windows). Done, and done.
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