Warehouse: 2FA/multifactor auth: policy on requiring recovery codes

Created on 18 Mar 2019  路  17Comments  路  Source: pypa/warehouse

As part of the work that @woodruffw is doing on 2FA here, I would like to add the following questions / help text to https://pypi.org/help/

I am posting this text here to receive feedback prior to making a PR:


How do I access my PyPI account using two factor authentication?

Users who have chosen to set up two factor authentication (2FA) on their PyPI account must provide a second method of identity verification (other than their username and password) to log in.

PyPI supports two 2FA methods: Generating a code through a TOTP application, and using a U2F security key.

How do I generate a code through a TOTP application?

When enabling two factor authentication (2FA) via TOTP in your account admin, you were asked to provision an application (usually a mobile phone app) in order to generate authentication codes. Popular applications include:

Open the application of your choice to generate a code. If you have deleted your application or lost your phone, you can still authenticate using a security key (if you have set up this 2FA method), or bypass 2FA using a recovery code.

How do I login with a U2F key?

A universal second factor (U2F) key is hardware device that communicates via USB, NFC, or Bluetooth. Popular keys include Yubikey, Google Titan and Thetis. PyPI supports any FIDO U2F compatible key.

Users who have set up this second factor will be prompted to use their key (usually by inserting it into a USB port and pressing a button) when logging in.

If you have lost your U2F key, you can still authenticate using a TOTP application (if you have set up this 2FA method), or bypass 2FA using a recovery code.

What is a recovery code?

When setting up two factor authentication on your account, you were provided with the option to add a set of 8 recovery codes, and instructed to keep these in a safe place.

These codes are usually a string of numbers, letters or words that act as a one time password. If you are unable to login to PyPI using your normal second factor, you can use one of these codes to bypass the 2FA process. Once you have used a backup code, you cannot use it again.

It is important that you store these codes securely by either printing or writing down the codes - we strongly recommend that you do not store them in a password manager, or on any device.

If you lose your recovery codes, and cannot authenticate with one of your 2FA methods, you will be locked out of your PyPI account. The PyPI team can manually grant you access to your account under limited circumstances.


@woodruffw a couple of questions:

  1. is the FIDO link appropriate? Or should I link to a different page, with different text?
  2. is These codes are usually a string of numbers, letters or words that act as a one time password accurate? Or would it be better to say "These codes are made up of numbers, letters and symbols"? e.g. I think this text is currently too generic and should be updated based on what our actual recovery codes will look like.
UUI

Most helpful comment

So, based on what I'm reading here:

  1. we are comfortable with making recovery codes optional, so long as we give users appropriate warnings
  2. we are prepared to offer users manual account recovery (this will require us to change the proposed help text above, which currently reads "The PyPI team cannot manually grant you access to your account.")
  3. we need to define a manual account recovery process

@di @ewdurbin @woodruffw do you agree with this summary? If so, let's open a separate issue for discussing manual account recovery, to keep things simple and close off this ticket? We can move over the comments on this thread.

All 17 comments

@brainwane I would appreciate your feedback on this, if you have time :)

  1. is the FIDO link appropriate? Or should I link to a different page, with different text?

No strong opinions but we could link directly to the specifications page: https://fidoalliance.org/specifications/download/

2. is These codes are usually a string of numbers, letters or words that act as a one time password accurate? Or would it be better to say "These codes are made up of numbers, letters and symbols"? e.g. I think this text is currently too generic and should be updated based on what our actual recovery codes will look like.

My original thought was to make the recovery codes identical in format to TOTP codes (i.e., 6 digits), but that may be a little too simple to discourage brute forcing (even with rate limiting). What do you think about making them hex strings? We could minimize some of the tediousness/eye-strain of typing hex characters with optional dashes, e.g.:

feed-cafe

If that sounds good to you, we could change the language to "[these codes are] a string of 8 hexadecimal characters, (optionally) separated in the middle by a dash" or similar.

I agree, I don't think 6 digits have enough entropy for recovery codes.

I think ten hex digits separated by a dash would be appropriate -- this is also what Github does:

image

(Don't worry, these aren't my recovery codes.)

I think ten hex digits separated by a dash would be appropriate -- this is also what Github does

Sounds good! That's what I'll go with.

Thanks for your feedback @woodruffw and @di.

Another question - @woodruffw - you mentioned that creating recovery codes should be optional, which is why the help text says "you were provided with the _option_ to add a set of 8 recovery codes".

Can you explain why we should make this optional? What is the use case for a user not to want recovery codes? It seems like playing with :fire: fire :fire: to me.

Sure!

Like you said, recovery codes bypass the two-factor process: an account that has 2FA + recovery codes is strictly less secure than account that has just 2FA. 2FA + recovery codes is still preferable to just a password, but my thought is that any action that decreases the security of an account should require affirmative approval from the user (which is also why the current TOTP removal form requires the user to type their password).

I think we can mitigate some of the hazard of users losing account access by offering them the option to add recovery codes immediately after adding a second factor (along with a warning about playing with :fire: if they don't). Does that sound reasonable?

From a support perspective, requiring recovery codes should cut down on the number of "unrecoverable account" requests we get as administrators.

From a support perspective, requiring recovery codes should cut down on the number of "unrecoverable account" requests we get as administrators.

Yeah, this would unfortunately increase the burden on administrators. There are additional steps that can be taken to minimize that, however: in addition to suggesting recovery codes after the user adds a second factor, we can add a flash to the management page/additional warning text in the two factor section, add it to an email that notifies them of their second factor, etc.

For context: GitHub, DigitalOcean, and Google allow second factor provisioning without recovery codes, while Dropbox appears to require them. So I can't defend it as a uniform practice :smile:

I'm +1 to @woodruffw's gameplay:

There are additional steps that can be taken to minimize that, however: in addition to suggesting recovery codes after the user adds a second factor, we can add a flash to the management page/additional warning text in the two factor section, add it to an email that notifies them of their second factor, etc.

Another idea...

This is a bit in the weeds, but... Is it possible we could implement a recovery process that doesn't strictly bypass MFA using recovery codes, but where those recovery codes... or even a single code... could be used as a "vouch" when requesting account recovery from admins. That would at least help expedite the process of admin assisted recovery.

Another option, for account recovery: make it possible but with a long delay:

  • wait 30 (or 60, 90 days) before you grant account recovery
  • ask at sign-up for phone number to text in case of account recovery request
  • email/text weekly with links that let you cancel the account recovery request
  • Notify maintainers on shared projects that someone on their projects has initiated account recovery. Presumably these people have alternative methods to contact the person who owns the account to get their attention and/or can remove the account from their projects if something seems suspicious. Also, optionally, permit shared maintainers to take ownership of a shared project during account recovery time if they suspect nefarious activity.
  • Optionally post notices on projects where a maintainer has requested account recovery during the waiting period and maybe after for a period of time (90 days?).

If recovery request does not get cancelled, assume it's legit and let it go through.

The above process, while being a bit non-standard and potentially embarrassing for someone who loses access to their account, still permits account recovery in a way that mitigates the potential for bad actors to unknowingly get access to a project and upload malicious code (which I assume is the main attack vector to be worried about with account recovery).

  • ask at sign-up for phone number to text in case of account recovery request
  • email/text weekly with links that let you cancel the account recovery request

SMS is completely broken as an authenticity channel, so adding texts to the recovery process would probably increase rather than decrease an attacker's chances of gaining access to an account. Email should be fine, with the normal caveats about phishing. But most of this pertains to the general account recovery process, not specifically how we handle 2FA recovery tokens or how we do account recovery when a user has enabled 2FA but lost their second factors :-).

  • Notify maintainers on shared projects that someone on their projects has initiated account recovery. Presumably these people have alternative methods to contact the person who owns the account to get their attention and/or can remove the account from their projects if something seems suspicious. Also, optionally, permit shared maintainers to take ownership of a shared project during account recovery time if they suspect nefarious activity.
  • Optionally post notices on projects where a maintainer has requested account recovery during the waiting period and maybe after for a period of time (90 days?).

Notifying maintainers on shared projects and posting recovery notices are great ideas, and I think both will follow from the audit log/trail work that Trail of Bits has been contracted to work on.

SMS is completely broken as an authenticity channel, so adding texts to the recovery process would probably increase rather than decrease an attacker's chances of gaining access to an account.

Keep in mind that with my proposal, SMS only allows you to cancel account recovery, it doesn't verify anything. If an attacker hacked your phone account, they would have to keep it longer than the waiting period so that you wouldn't get the cancel notification by text. Assuming anyone would notice and rectify that their phone no longer worked in 30? days, then I don't see how using SMS in this fashion is a negative.

Yep, I think I misunderstood! In that scenario, SMS would be just fine.

So, based on what I'm reading here:

  1. we are comfortable with making recovery codes optional, so long as we give users appropriate warnings
  2. we are prepared to offer users manual account recovery (this will require us to change the proposed help text above, which currently reads "The PyPI team cannot manually grant you access to your account.")
  3. we need to define a manual account recovery process

@di @ewdurbin @woodruffw do you agree with this summary? If so, let's open a separate issue for discussing manual account recovery, to keep things simple and close off this ticket? We can move over the comments on this thread.

@nlhkabu that sounds like a great gameplan to me.

@nlhkabu +1 from me.

Closing off this issue, as I have now opened #5758.

The conclusion here is that we will offer manual account recovery. I have updated the suggested help text to be:

The PyPI team can manually grant you access to your account under limited circumstances.

I suggest that once we define the account recovery process in #5758, we add this information as an additional FAQ, linking to it from this sentence.

Was this page helpful?
0 / 5 - 0 ratings