views:

830

answers:

5

I am creating a web app that will use OpenID logins and OAuth tokens with Youtube. I am currently storing the OpenID identity and OAuth token/token secret in plain text in the database.

Is it inappropriate to store these values as plain text? I could use a one-way encryption for the OpenID identifier but I don't know if that is necessary. For the OAuth tokens, I would need to use a two-way encryption as my app relies on getting the session token for some uses.

Is it necessary to encrypt the OpenID identity? Could someone use it to gain access to a user's account?

+2  A: 

I don't think it's necessary. An OpenID identity is basically like a username. There really isn't much need to conceal that; even if someone stole it, they'd still need the password to log in through the associated site. With Google's implementation, it's even more worthless. The OpenID isn't even a username, or email address, or anything. It's a random string that you can't really use at all.

The OAuth tokens... I don't know quite as much about those, but I suspect you wouldn't need to encrypt them either. The OpenID authentication is actually pretty clever, and prevents you from using the same token twice (I believe); at least, if the consumer code is implemented properly (should be, if you're using a good library).

Edit: Apparently you should treat OAuth tokens as passwords. So ignore the second paragraph :)

Mark
OAuth token *secrets* are as sensitive as passwords and should be encrypted where you would encrypt a password.
Andrew Arnott
@Andrew: I guess I'm thinking of the nonces? Those are separate?
Mark
+2  A: 

There's two schools of thought here.

The first argument is that: you should treat OAuth tokens like passwords. If anyone were to access your database, obtain all the OpenID/OAuth pairs and run an man-in-the-middle attack, they could impersonate any user on your site.

The second argument is this: by the time someone has access to your database and sufficient access to your network to run an man-in-the-middle attack, you're hosed anyway.

I'd personally err on the side of caution and just encrypt them; it's a standard practice for passwords, so you might as well give yourself just that little extra peace of mind.

Meanwhile, Google has this advice:

"Tokens should be treated as securely as any other sensitive information stored on the server."

source: http://code.google.com/apis/accounts/docs/OAuth.html

And some random guy on the web has specific implementation advice:

  • If they’re on a regular disk file, protect them using filesystem permissions, make sure that they’re encrypted, and hide the password well
  • If they’re in a database, encrypt the fields, store the key well, and protect access to the database itself carefully. *
  • If they’re in LDAP, do the same.

http://brail.org/wordpress/2009/05/01/implementing-oauth-take-care-with-those-keys/

Ben Walther
A: 

OpenID URL shouldn't be encrypted because this is your "open id" literally, everyone should know the value. Besides, the URL needs to be an index in the database and it's always problematic to encrypt the index in the database.

OAuth token/secret should be secret and encryption may improve security if you have to store the token long term. In our OAuth consumer application, token/secret is only stored in session for a short while and we choose not to encrypt them. I think that's secure enough. If someone can peek into our session storage, they probably have our encryption key also.

ZZ Coder
Not quite true. OpenID URLs aren't necessarily public. To prevent correlation between RPs, Google uses directed identity so that every RP gets a unique OpenID for the same user. If all these were made public so that literally everyone knew the values, correlation would again be possible.
Andrew Arnott
OP is talking about back-end database. It that were public, you have much bigger privacy issues to deal with.
ZZ Coder
+1  A: 

The OAuth Token and Secret should both obviously be kept safe in your database, but you can't store them using 1 way encryption the same way you would for a password. The reason being is that you need the token and secret to be able to sign the request.

This would also be the case if you are running an OAuth server, you still need the original token/secret to verify the request.

If you want to you could still encrypt them using a 2 way encryption algorithm such as AES to offer security in case your database or database backups get compromised.

Pelle
Other answers say treat them as passwords, but this answer is good in that it points out you need a 2 way encryption algorithm. With hashed passwords you can hash what the user types and check against the hashed password. With tokens and secrets you need to get the original text back again.
paulmorriss
+3  A: 

I might be wrong but ...

first there is an registered application that have consumer_key and consumer_secret ... these are also important ...

when user authenticate and "allow" your registered application you get back: access_token that is considered as user "password" and would allow JUST YOUR application act on users-behalf ...

So getting just users "access_token" from your database won't help much if they don't have consumer_key and consumer_secret to make access.

I think that service provider compares all four parameters on request ... This way would be smart to encrypt these 4 parameters before storage and decrypt before response . This is just when you need to update or make changes on users-behalf of user account service provider. To keep them logged in on your site use sessions ...

Feha