8

I'm dealing with a 3rd party vendor that clearly does not understand security - to access their API from my back-end I have to supply the end user's ID/user/password for the 3rd party service with each batch of requests.

I'm fighting with them to at least implement some sort of revocable token based authentication, but in the mean time I have to deal with this (at least they use HTTPS... sheesh).

I have to authenticate fairly regularly for synchronizing data, and sync has to happen without the end user's intervention, so that basically means the BE has to store the credentials in a reversible format. I'm not naive enough to store it in plaintext, but even if I encrypt it in the database the key won't be very far from the lock, so to speak.

If they didn't have a metric ton of confidential data stored there I'd be less concerned, but this is definitely data worth securing. Any tips?

Notes:

  • The passwords would be stored in a distributed database. The database itself is reasonably secure. The only real chance of a breach would be a leak of one of the developers' credentials to directly access the data, or a serious programming mishap.
  • The vendor's API does not allow programatically changing the password, so rotating passwords is not an option.

Access to the back-end's source code could be locked down pretty tight. Would it be reasonable to store a private key in the source and call it a day?

jdiaz5513
  • 81
  • 3
  • First off, have you had a look at the questions in the 'Related' tab to the right? They may hold an answer that works for you. – Rory Alsop Aug 30 '13 at 14:23
  • 2
    I did. This one was the most promising: http://security.stackexchange.com/questions/17319/is-it-worth-the-effort-to-store-ftp-passwords-encrypted?rq=1, but "nah, don't bother" is not acceptable in my case... the data really is sensitive. – jdiaz5513 Aug 30 '13 at 14:58
  • 1
    Fair enough :-) – Rory Alsop Aug 30 '13 at 15:04
  • 1
    You're not really left with much of a choice here. I would say reversible encryption along with locking down permissions to who/what can get and store the passwords and setup auditing to monitor who/what got or set the password and when. I think that's the best you can do in this situation. – Four_0h_Three Aug 30 '13 at 15:31
  • I feared as much. I'm going to get on the vendor's case about it. I'll leave the question open for a while in case someone has something enlightening/clever to contribute. – jdiaz5513 Aug 30 '13 at 17:27

2 Answers2

5

The best you can realistically hope for is to use whatever features the local OS provides for storing "secrets". This means DPAPI on Windows, Keychain on MacOS X... use this to either store the user password, or some decryption key for an encrypted file which contains the user password. OS-level features may have a more direct access to hardware than what you can do at application level, and, as such, offer a possibly stronger (less weak) protection against attackers. Also, you cannot be blamed for having used the "OS recommended" method of storing secrets.

If the client machine is stolen altogether, you still have to assume that the attacker will be able to recover the user password. Possible mitigations include using an autolock feature on the client machine coupled with hard disk encryption (but this is outside of your reach as an application writer, and the human user might not like the idea). The autolock means that the attacker will find it difficult (not impossible, but difficult) to mess with the machine while it is still on, and hard disk encryption means that rebooting the machine permanently locks the attacker out of the stored secrets (the disk encryption password has to be typed in every time the machine boots).

Thomas Pornin
  • 320,799
  • 57
  • 780
  • 949
  • Good answer, but wrong question... the "secrets" are being stored in a distributed database where I have no direct control over the host machines. I should have been more specific in the question. (For what it's worth, the database itself is reasonably secure.) – jdiaz5513 Aug 30 '13 at 15:14
0

This is not unheard of when dealing with third-party APIs. Even if they provide you with a "token" instead of a password, those tokens effectively give you access to the account (although in many cases they are limited in some way), so they need to be protected carefully. Solutions I am aware of:

  1. Store the username/password in the source code. Since this is so easy, people do it all the time. However, it makes me nervous: ideally your code is in source control, so anyone who ever has access to that will have the credentials.

  2. Store it in a configuration file (ideally with limited permissions so it can't be read by unauthenticated users, etc). I personally find this to be slightly better than #1, since ideally there should only be very few copies of this.

  3. Store it in RAM, and get the password from the user or over the network when it starts or is needed. This is probably the most secure, but either inconveniences the user, or requires an "encrypted credentials" service.

I think that for most applications, the configuration file solution (#2) is reasonable, assuming you generate a random password for this account that isn't reused anywhere else, and the system itself is reasonably secure. For really important things, you may want to go down the path of only storing the credentials in memory.

I used that approach recently to give a server an encryption key for critical data in a database. It means if the server is restarted, someone must manually type in a passphrase, but it also means that if someone walks off with the disks, they don't get the data.

Evan Jones
  • 101
  • 1
  • The credentials are actually per-user (it's the user's data that I'm trying to protect), but this does give me an idea... – jdiaz5513 Aug 30 '13 at 23:02