8

I realize that in general, you should not store user credentials directly (i.e., in plain text); rather, it is best to store some encrypted form of them.

However, suppose I create a website that interacts with some other 3rd party site; and let's say this 3rd party site offers an API that requires the user's credentials (with that site) for authentication.

If my goal is to, say, provide a superior UI or introduce additional functionality on top of the services provided by this 3rd party, then it seems to me I need to actually store the user's credentials somehow so that I can use the API—not the user's password for my site (I can hash & salt that one), but for the external site.

Is there a "right" way to do this? My initial thinking is to store the credentials encrypted in some form such that they can be decrypted on the server for purposes of making API calls to the 3rd party service. This would mean that an attacker would need to understand how the encryption/decryption works in order to steal the user's external passwords. However, that does not seem so far-fetched to me; a clever hacker who had already breached the server hosting my application would probably be able to get at the code and figure it out pretty easily.

So, that approach seems like better than nothing but not exactly great. Are there other strategies that people use? Is this entire concept (interacting with a 3rd party service requiring user credentials) ill-advised?

I have to believe there is at least some reasonably secure way of dealing with this situation since it seems relatively common among even some fairly high-profile websites (e.g., Mint.com).

Update: Just to clarify: I am aware that in an ideal world, the 3rd party service would implement some version of OAuth (or an equivalent) so that I would not have to store credentials. Unfortunately, the reality in this case is that the 3rd party service requires user name and password to be sent in every API request. So is the consensus that I'm hearing, then, that in this case most developers would just refuse to use the service (and most likely suggest to them that they implement OAuth)?

Dan Tao
  • 125,917
  • 54
  • 300
  • 447
  • 2
    The "right" way to do this is using [OAuth](http://oauth.net/) which the third-party website has to support. (Or some other similar authentication method they implement in their official API.) The way OAuth works is that what you store in your application is an authentication/authorisation token the validity of which the third-party website can control. – millimoose Sep 27 '12 at 19:46
  • ^ This should be an answer so i could upvote it – j_mcnally Sep 27 '12 at 19:50
  • @millimoose: Sure, that would be great if the third-party website supported OAuth. In this case, they don't; all API calls require basic HTTP authentication. – Dan Tao Sep 27 '12 at 20:27

1 Answers1

6

IMO opinion you should not take responsibility to store the credentials somewhere on your file system. Just think that even the 3-rd party server does not know the user credentials (would have the hash of the password and not the actual password stored).
I would recommend to store them as part of an http-session which lasts as long as the session is active.

Cratylus
  • 52,998
  • 69
  • 209
  • 339
  • Think of like having keys to a safe. If you don't have the keys, you are never a suspect if things go missing. Likewise, if you never see the credentials, you can't ever be blamed (right or wrong) if those credentials are misused. – Jeremy J Starcher Sep 27 '12 at 20:02
  • 1
    While I understand the concerns raised by you and others about storing credentials, I found your final recommendation (storing the credentials in the session) to be pragmatic and helpful. It's obviously a compromise, but I think it's the best solution in this scenario. – Dan Tao Sep 28 '12 at 16:08