4

I'm doing some relatively amateur C# development for a small customer support team and working with the SalesForce API in my application. With SalesForce, login using the API requires you attach a Security Token to the password. Because my users are finicky, it's going to be necessary for (only) the Security Token to be stored in the application database so they aren't needing to enter it every time they use the application.

I'm hoping to get some advice on the best method of keeping this reasonably secure as this is my first venture into any kind of serious security. I've been doing some reading and picked up the AESThenHMAC encryption/decryption method from this post.

My thoughts on the process are as follows:

  1. On first login to the application, the user is prompted for their username, password and security token.
  2. The security token is encrypted using the SimpleEncryptWithPassword from above with their password as the 'password' parameter and stored in the database.
  3. On subsequent logins, the user is prompted for their username and password, the security token is retrieved and decrypted, then the user is logged in using the SalesForce API.

My questions are:

  • Does this provide a reasonable level of security for the storage of the Security Token?
  • If not, why not and what can/should I do to improve it?
  • If so, which of the following is the better method of indexing the Security Token by the username in the database?

    1. Username is Plain Text
    2. Username is hashed
    3. Username is encrypted in the same manner as the Security Token

Thanks in advance for any advice/help/input.

2 Answers2

4

The point of CWE 257 is to force the authenticating app to evaluate passwords not by decrypting them and comparing to the plaintext, but by encrypting (or actually hashing) the plaintext again and comparing the opaque texts. But yours is not the authenticating app; it's technically the client. Apps have to store the passwords to back end systems all the time, there's no way around it. Heck, even my browser stores passwords from time to time.

In addition, the attack vector detailed in CWE 257 doesn't apply here. An admin can't actually decrypt the token without the user's password, because the password is the key. So in my opinion don't worry about it.

Overall I think your idea is fine. You might considering binding to the device (e.g. set a secure persistent cookie with plenty of entropy) and requiring the user to re-enter the token when switching devices.

One weakness is that the user will need to go dig up his token again if he ever changes his password; this may discourage him from changing it often enough. Then again it sounds like your primary user base can't be bothered with things like that anyway.

John Wu
  • 9,101
  • 1
  • 28
  • 39
  • Thank you for your response. Your thoughts mostly mirror my own, but as I said, first time doing security things so I thought it'd be a good idea to get advice. SalesForce itself forces a password change every 3 months, so that's already taken care of for me. I will definitely take your advice on doing some device binding, as there are only ~8 users (who always use the same machine) that have any business running the application anyway. – Jdinklage Morgoone Nov 20 '13 at 01:38
1

This proposal is not a good method of storing authentication credentials. most notability it is a violation of CWE-257. Passwords must not be store din a recoverable format, ever, no system should rely upon this design. Storing passwords in this way is also a violation of CWE-916, using bcrypt is a better alternative.

rook
  • 46,916
  • 10
  • 92
  • 181
  • 2
    Thank you for your response, but I think you may be misunderstanding what I'm doing. Passwords are not being stored, only a secondary Security Token that the API requires be attached to the password in order to log in. At no point does their actual password get stored anywhere except in the application's memory at the time of the login. – Jdinklage Morgoone Nov 19 '13 at 19:27
  • @Jdinklage Morgoone Authentication credentials, such as passwords, "Security Tokens", API access tokens, session ids, password reset tokens or any other secret used in the process of authentication must be protected, and this proposed system is missing this protection. – rook Nov 19 '13 at 19:31
  • 3
    What would you suggest I do instead, then? The Security Token that the API requires is string of 24 characters that's unreasonable to memorize, but is required for my users to log in. They can't be asked to enter it every time they launch the application. Given the low accessibility of the data to begin with, and the low impact should it be compromised, I'm not sure I understand why storing only one half of an authentication credential, which is 100% useless on its own and difficult for a user to remember, is so dangerous. – Jdinklage Morgoone Nov 19 '13 at 19:39