"Save Password" functionality


#1

Some preface:

  1. Our application is killed by mobile OS quite frequently (often this happens while app stays in the background), and this forces users to go through logging form after each crash. This happens to other applications as well, the frequency of such events depends on app’s performance (os might kill the app which consumes too much cpu or ram, etc) and also on the resource restrictions and state of the particular device. For instance, if Status is the only app which is running on the device it might happen that it will not be killed for weeks. But that’s rarely the case.
  2. The suggested approach to bypass this issue was to restore the last known state of the app on the next run, or at least log in without password prompt. It was partially implemented (only for iOS) here https://github.com/status-im/status-react/pull/5617 . The password is stored as a plain text in the keychain if a user switches on “save password until logout”. When user internationally logs out the password is removed from the keychain.
  3. There was also a request for implementation of the same functionality on iOS, as it was postponed because of security concerns https://github.com/status-im/status-react/issues/5793
  4. I opened a PR which enables “Save Password” functionality on Android 23+ https://github.com/status-im/status-react/pull/6616, but @cammellos raised the concern that storing a plain password on the device is a wrong way to go
  5. we decided to close that pull request and continue the discussion here

next steps

  1. We suggested that “Save Password” functionality should be disabled on iOS until we figure a better approach
  2. We can stop using a plain password when a user creates/restores account. We can hash it before ever passing to status-go. In this case, there is no need to store a plain password on the device. This change will require migration for realm db (as it will be encrypted with a key derived from the password’s hash but not directly from the password) and also functionality for changing account’s password on status go side (if such doesn’t exist already)
    former steps are not that clear
  3. derive time-based token which will be stored on the device and used as a password. Not clear how to implement this, because password (or its derivatives, token in this case) should be used for realm db encryption, which means that the token will be needed on the next run and can’t disappear (expire) because access to can be lost.
  4. On Android we can temporarily store password (rather its hash) in memory using a service in the background (with no guaranty of persistence, service might be killed at any point in time), which would allow as to reuse password if the app was closed but service hasn’t been killed. Storing time-based or some randomly generated token in the service will not work at least for realm db (same reason as 3)
  5. We can have a separate PK for whisper and for the funded account. In this case, we can have separate passwords for them and even if whisper key will have all the same problems which a single key has now, the password for the funded account will not be required for logging in, thus no need to store it in any form, funds are safe.

So open questions are:

  1. Is storing of the password’s hash on device instead of password enough for us? @petty’s quote on this

how that private key is (en/de)crypted shouldn’t also be on the same device, unless stored in a separate key-manager app like lastpass (outside the realm of status development)

  1. if not, what measures must be taken?
  • store keys only on a secure enclave
  • time-based token
  • seprate keys for whisper and funded account
  • something also
  1. Are there other solutions which were not mentioned?

#2

Re: separating keys

  • this must happen within Status. by using the same key for everything, we decrease the available privacy features, we increase security risks of the consequences of exposing said keys, among other things.
  • The risk profiles of various functionalities that are based in the keys are drastically different. The process of optimization around one functionality will inherently have consequences on other functionality when they are linked. This must stop, as it may lead to unintended security and privacy problems in the future.

#3

@hester, @andmironov, @patrick have more to say about the user flow of this, as we’ve been working on it over the past few weeks. They might want to chime in. I’m don’t think we’ve reasoned much about the authorization/authentication associated with the various keys, though. As for what this will potentially look like, I’ve created a key-diagram:


#4

How does this look like when using fingerprint/faceid auth? Surely we can move the key to secure enclave on device if not using the hardware wallet?


#5

a few remarks on implementation details

iOS

  1. We store the password in a keychain entry with a very specific set of flags, that, according to the docs don’t allow it to leave the device: no cloud sync, no backing up of any kind, no migrating to a new iPhone when you transfer everything in any way.

  2. There is one more flag that protects this keychain entry with biometric auth, so no app never can read it w/o a user being shown the biometric auth window.

  3. We can improve the mechanism of storing the password by encrypting it with a key generated inside the secure enclave (this key is never exposed at all, the API is basically “encrypt with this key”/“decrypt with this key”). That probably makes it a tad safer.

Though the core issue with that we have the same key and the same encryption key for both Whisper (that we need to sign-in) and ETH itself (related to funds), I agree with @petty. So, theoretically, we need to focus on that first.

Also, we need some very clear explanation about storing the password on the phone, it still should not be recommended to use this feature is a user has a lot of funds and we need to promote our hardware wallet there too.


#6

Some additional context. In the meetings around identity, we have indeed not discussed authentication. Excellent point that we need to consider this.

Our focus has been to specify current identity structure and propose an identity structure that likely more closely resembles peoples mental model of a web3/identity. The reality of key generation might also be slightly different from how the structure is presented, if this aids understanding.

For example: we might present the Whisper key as core identity even if it is derived from a master wallet key. Also, we might present individual keys as account profiles that can be unlocked through a single account password.

In short, we’re still looking at how to balance a technically accurate representation with a more human-friendly interpretation.