Facebook and all OAuth applications (facebook is sort-of OAuth) provide access tokens for applications to do things on behalf of users. I’ll not go into details of how to obtain them and how to use them, but in most cases you would want an eternal token – i.e. one that can be used for offline access. OAuth 2 defines a way to obtain new tokens by passing an expired token, but facebook does not support that, and it is mostly the same as an eternal token.
So you have to store the token in the database (for web applications, that is) so that you can use it the next time the user comes without asking him to authenticate again and again. But if an attacker gets hold of your database, then he can do whatever he likes on behalf of all your users. And that’s something you don’t want.
So you must store them securely. Each guide tells you that, but they don’t make it clear how. What are the options when the “security” is mentioned:
- store a hash – not feasible in this case, because you must be able to obtain the original token
- encrypt with an asymmetric algorithm (RSA) – not needed – both encryption and decryption is done by the application
- encrypt with a symmetric algorithm (3DES, AES) – this seems to be the best option. Prefer AES.
So, you now have the access token encrypted and stored in the database. Each time you need it, you decrypt it, and use it? No – decrypt it and store it in the user session (and transient, so that it does not get persisted if the session is)
So where do you store your AES key? Somewhere in your application. Is that completely secure? No, because if an attacker gets access to your system, he will be able to get the key and decrypt the database values. But it is still better than storing them in plaintext in the database.
The thing is, you can’t actually make it more secure. You can go through another X layers of key/password storage systems each of which gives you a key/password based on another key/password, but once an attacker gets to your system, all of that is “security through obscurity”. It’s because your application must be able to obtain the access token somehow. And if an attacker owns your application, then he can obtain the tokens as well.
So what you should do is – report breaches into the system, so in case an attacker gets access to your system (not only the database, but the application/file system), you can disable your facebook/twitter applications, or invalidate the tokens (if the service allows it), so that no harm is done.