How password is changed

Egor Homakov edited this page Jun 12, 2017 · 3 revisions

Let's start with reasons. The only reason to change a password is when the user believes it was compromised, or could be compromised in the future. Ideally, the change must be as fast as possible: every second counts because the attacker can do the same once they have account credentials.

This is why rotation of credentials is part of the protocol. Every client must implement a GET /securelogin endpoint that behaves like this:

  def securelogin
    response.headers['Access-Control-Allow-Origin'] = '*'
    obj = SecureLogin.verify(params[:sltoken], change: true)
    if obj[:error]
      html obj[:error]  
    elsif @user = User.find_by(securelogin_pubkey: obj[:securelogin_pubkey])
      new_obj = SecureLogin.verify(obj[:scope]["to"])
      if new_obj[:error]
        html "invalid_new_token:#{new_obj[:error]}" #new token is invalid
      elsif User.exists?(securelogin_pubkey: new_obj[:securelogin_pubkey])
        html "pubkey_exists"
          securelogin_pubkey: new_obj[:securelogin_pubkey], 
          securelogin_secret: new_obj[:securelogin_secret]
        html "changed"
      html "not_found"

On the surface in UI it looks like a regular password change (Password Change button and New Password input) but under the hood it derives a new profile with email=current email and pw=new pw. Then it hits the list of providers and tells them to change from old profile to new one. When all providers are notified and respond with changed, the credentials based on old pw are replaced with new generated key.

When provider receives an sltoken with scope=mode=change&to=new_token it must make sure its valid with verify method. Then it finds the user with given pubkey, and verifies given new_token (which is regular sign in token ie it has empty scope). If all checks passed, pubkey and secret must be changed to new ones from new_token.

Most important question is how do we get the list of providers we used this profile with? Here are the options to consider:

  1. Manually enter the list - always an option but the user must not forget anything, so let's find something more convenient.

  2. Load from localStorage (visited is an array of visited providers). If you retain access to your device, it has everything you need. If original device is lost, we recommend to check history from other devices where it was used + enter manually + add a list of top 1000-10k websites.

  3. Every usage is tracked and stored on central authority as relation pubkey<->provider. The user can request their history and add to the list so nothing would be missed at all. Could be encrypted (No Knowledge) but initially is plain text for analytics purposes.

  4. Meanwhile using the stats we can figure out most popular providers (1000-10k most used) and share the list with other websites or build-in the client. This is to make sure most important account will be changed first and for sure (and if something goes wrong with the history database). Other less critical accounts can be updated manually (1).

Currently SecureLogin implements 1 and 2 offering a textarea where user sees providers from localStorage and can add some manually. (4) will be added once it gets any adoption (a dozen of services). 3 (per-user history) could be added in the future, but should never be single point of failure - without centralized history 1+2+4 are entirely functional and convenient enough to cover most cases.

Clone this wiki locally
You can’t perform that action at this time.
You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session.
Press h to open a hovercard with more details.