2

I have an online application that I'm adding MFA to, using the Google / Microsoft Authenticator apps for mobile phones. I've tried to adopt a security focussed approach to storing the MFA secret and at the moment, that secret is being encrypted using the users password within a database field. We don't store the password itself but the hash of the password and use it to compare to the users submitted password at run time for comparison.

I'm now realizing that there's a flaw in this methodology and that's when the user forgets their password and requests a password change. At that point, we've no way of decrypting the users secret (using their old password) so that we can re-store the secret using the submitted new password.

I was wondering how others deal with this? To my mind we have the following choices:

  1. We force the user to set up their mobile app again with a new secret
  2. We encrypt the secret, not to the users password, but to another form using another encryption string

I guess that (1) is the easiest but not the best for the user - they'd have to remove their (former) account from the app before scanning a QR code (or equivalent) to set up a new account.

(2) I like the idea of, but wonder how we should go about that. I thought of perhaps taking a hash of the users email address and using that as the encryption string as we can programmatically restore everything without the users password, but not sure that's secure enough?

Can anyone give me some guidance here as to where to look for possible solutions?

2
  • 1
    Why exactly don't you like 1? It's the right way to do it. – Joseph Sible-Reinstate Monica May 11 '20 at 19:54
  • @JosephSible-ReinstateMonica It's not really a case of not liking (1) but rather asking the opinions of others out there if this is, in fact, the way to go. I can't control how end users can update their account on their mobile devices and from history, I know there's an amount of "security vs usability" backlash that we can expect, that's all. I was really just asking if this is the most appropriate action, in this case... – bnoeafk May 12 '20 at 0:45
3

I guess it all depends on your thread model and szenario. I am reading between the lines that you are afraid of what will happen if an attacker gets access to the table containing the 2FA secrets, for example by a leaked backup or SQL injection.

If this is the case, you can encrypt the secrets with a systemwide key, that is loaded into your application from some key vault. This decouples where the key is stored and where the encryped secrets are stored. But your application needs to have access to both.

If the key is derived from the user, there is always the danger that an attacker could do the same.

In my last project we decided to create dedicated MfaService, written in a different language and using a different datastorage compared to the rest of the Application. The service was written in a way that it can store the secret and check a code for validity, but never reveal the secrat again. The User Service only stored a reference to the MFA Credentials. Thus, an attacker would need to access both services, which was good enough for our usecase.

1
  • This is the way how commercial solutions do it. After all you want to be able to access the 2nd factor secrets. The systemwide encryption key is simply not accessable in the database. So dumping the database is not enough to get the OTP secrets. Your vault could be anything from a key file to an external hardware security module. – cornelinux May 24 '20 at 11:53
0

I ended up storing the MFA secret encrypted according to the user's password as I believe that's the most secure way of doing so. When the user comes to change their password (which they have to every 90 days) I have to decrypt the secret using their old/existing password and then re-encrypt using their new password - it was a little more work than I had intended on doing, but I'm comfortable that the security is in line with other security factors that I'm working to.

3
  • How do you solve password resets, since you have no way of decrypting the secret now? – pandaadb Jan 13 at 10:06
  • Password resets are the same as a new user with no secrets at all - they have to be regenerated, including getting the user to scan a new QR code etc etc. – bnoeafk Jan 14 at 19:13
  • Interesting, that would mean to accept the fact that if someone has access to an email, they can bypass and remove MFA for an account. – pandaadb Jan 15 at 9:17

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.