New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enable 2FA via Email or TOTP for Developer Accounts #732

Open
davismtl opened this Issue Jun 5, 2018 · 26 comments

Comments

@davismtl

davismtl commented Jun 5, 2018

Initially Filed Here:
https://bugzilla.mozilla.org/show_bug.cgi?id=1466712

Context
Chrome extension developer accounts were compromised in 2017 resulting in malicious addons being pushed to Chrome users. This could have been prevented by 2FA.

https://arstechnica.com/information-technology/2017/08/after-phishing-attacks-chrome-extensions-push-adware-to-millions/

Firefox Accounts

Since Q1, FxA has the capability to require certain logins to go through a verification loop.

This verification loop can be done by email where the user has to enter the codes we emailed them. ( See Bug 1432189 )

Alternatively, as of this week, for increased security, it is possible to force users to enable 2FA via TOTP. For example, this will be forced for IAM team's integration of FxA into Auth0.

Description
Enable at a minimum email confirmation loops for developer accounts.

If desired, force developers to turn on TOTP. (increased friction over checking an email due to effort to setup)

@eviljeff

This comment has been minimized.

Member

eviljeff commented Jun 5, 2018

Can you link to any docs that describe how AMO would signal to FxA this was an account in need of email confirmation (and/or TOTP)?

@davismtl

This comment has been minimized.

davismtl commented Jun 5, 2018

@vbudhram is getting together the documentation for this and will link to it here.

@vbudhram

This comment has been minimized.

vbudhram commented Jun 5, 2018

@eviljeff This link is a good summary of how to request a user's verification status during login and what the corresponding values mean.

These values can also be requested from profile server. In the case of TOTP, we would report acr: AAL2 and amr: ["pwd", "otp"]. At this point, AMO could choose to let the login proceed or put up a screen with links and instructions on how to enable TOTP on a user's account (or both?). The IAM team is doing something similar to that.

For the case of email codes/links, we would report acr: AAL1 and amr: ["pwd", "email"]. Verifying with TOTP is considered more secure than using an email loop. Currently, there isn't a way for the oauth relier to force verification on one type of account when using codes/links. It would be all accounts or none. That being said, I'll confirm with @rfk about what needs to be done there.

If you wanted to give this a try, it is available in our production environment. I don't believe you have to do anything special besides what was documented in the link above.

@rfk

This comment has been minimized.

Member

rfk commented Jun 5, 2018

If desired, force developers to turn on TOTP. (increased friction over checking
an email due to effort to setup)

FWIW, I think we should do this one, and require developers to enable a proper 2FA mechanism on their account. This would make the requirements for AMO developers the same as those for Mozillians using FxA to sign in to airmo or other internal Mozilla services, and is similar to the requirement that all github accounts that can push to production mozilla code have 2FA enabled.

It's possible for AMO to check a user's 2FA status today, by looking for the "twoFactorAuthentication" flag when you fetch the user's profile info:

https://github.com/mozilla/fxa-profile-server/blob/master/docs/API.md#get-v1profile

It would be slightly more secure to use the OpenID Connect id_token flow that Vijay linked to above, at the cost of larger code changes on the AMO side.

@diox

This comment has been minimized.

Member

diox commented Jun 6, 2018

Currently, there isn't a way for the oauth relier to force verification on one type of account when using codes/links.

One idea we're exploring is for 2 factor auth to be opt-in in AMO, and strongly suggesting developers to enable it. That would make the transition a lot easier on the users - this is especially important because we have a lot of users who aren't technical people or do not pose that much of a threat (theme developers and end-users that have an account just to rate add-ons).

Rough idea of what the process would look like:

  • The user tries to log in through FxA as normal - after having successfully authenticated through FxA, they get redirected by FxA to our endpoint that verifies their AMO account, like it's currently happening.
  • At this point we'd pull the user data from our database and determine whether they need 2FA and if they have already provided it.
  • If it's already present or not required for this account, we log the user in as normal
  • If it's missing and required for this account, we'd go back to FxA asking for the 2FA step to be completed
    • FxA would ask the user for the 2FA and redirect back to our endpoint with the info, and this time we could log the user in.

That means we do need a way for us to redirect the user to FxA asking for that 2nd factor. Does it make sense? Is it possible? Should we do this differently?

@rfk

This comment has been minimized.

Member

rfk commented Jun 7, 2018

I think this makes sense.

That means we do need a way for us to redirect the user to FxA asking for that 2nd factor

On the FxA side, it would mean we need to get around to implementing this:

mozilla/fxa-oauth-server#520

@diox

This comment has been minimized.

Member

diox commented Sep 19, 2018

Worth pointing out that the alternative is just for AMO to communicate to developers that they can just enable 2FA themselves on their Firefox Account, and then... do nothing else on AMO side ?

@davismtl

This comment has been minimized.

davismtl commented Sep 19, 2018

@diox
IIUC, there was a desire to secure dev accounts to reduce the likelihood of an add-on being compromised and being pushed out to users. A practice that was put in place for Chrome extension developers last year.

If we merely want to let people know that they can better secure their accounts then sure, you could just communicate with users. But if you want to better secure developer accounts to prevent any malicious code from landing in Firefox then you'll want to detect 2FA and enforce it.

2FA is being imposed at Mozilla on Bugzilla and Github to avoid malicious code landing in the browser. I suspect these are similar threat models but perhaps to a lesser extent via addons/webextensions.

@diox

This comment has been minimized.

Member

diox commented Sep 19, 2018

I'm fully aware, but AMO is blocked on the upstream issue mentioned above to force it for developers.

@davismtl

This comment has been minimized.

davismtl commented Sep 19, 2018

@vbudhram I know you have been working to unblock this for the AMO team and that you even demo'd it this week. Can you share an update here?

@vbudhram

This comment has been minimized.

vbudhram commented Sep 19, 2018

Sure, the initial phase of this feature is on track to land within a train or 2. When it does land, any Oauth relier would be able to force a user to have TOTP enabled before continuing the login.

Summary of steps:

  • During the Oauth redirect to FxA, the relier would append arc_values=AAL2 on the url.
  • When user attempts to login, FxA will check if TOTP is enabled on account else display a message with instructions to enable it.
  • If it is enabled, the login would proceed and user would be prompted to enter their code.
  • Upon successful login, the relier will able able to verify that the session was indeed verified with TOTP using #732 (comment).

Unfortunately, this version just displays an error and link, but eventually we would like a nicer landing page with links to directly set it up within the login flow. Here is a recording of it using our test relier 123Done.

@diox

This comment has been minimized.

Member

diox commented Sep 19, 2018

We don't want to force 2FA on all users though, only developers. We only know they are a developer once FxA gets back to us with the user information that tried to log in.

See my previous comment : can FxA handle the last 2 points I described there ? At this point the user would technically be authenticated, but we need to force them to go back to FxA for the 2nd factor and only that - they shouldn't have to provide their password again since they just did that.

@davismtl

This comment has been minimized.

davismtl commented Sep 20, 2018

We don't want to force 2FA on all users though, only developers.

Yes, we understand that. We don't want that either. Unfortunately, we don't have the means to distinguish which users are developers so you'll have to do that for us. You will have to pass to us arc_values=AAL2 when you want us to enforce 2FA on a developer.

If it's already present or not required for this account, we log the user in as normal

Yes, the device keeps the sessionToken in localStorage then they won't need to 2FA again on that device. They expire after 4 weeks.

If it's missing and required for this account, we'd go back to FxA asking for the 2FA step to be completed

  • FxA would ask the user for the 2FA and redirect back to our endpoint with the info, and this time we could log the user in.

In this first iteration, we will display an error that you now require 2FA to be enabled. We will include a link that opens in a new tab that explains to users how to enable 2FA.

IIUC, initially, we will not have users set up 2FA within the same flow but rather in a different tab, we are investigating having the original tab redirect to your endpoint once 2FA setup is complete. @vbudhram can you confirm that I understood this flow properly?

I suspect that in the future it would not be unreasonable to have the 2FA setup within the same flow without opening a new tab.

@rfk

This comment has been minimized.

Member

rfk commented Sep 20, 2018

At this point the user would technically be authenticated, but we need to force them to go back to
FxA for the 2nd factor and only that - they shouldn't have to provide their password again since they
just did that.

This should be workable, although I expect the "shouldn't have to provide their password again" part will require changes on the FxA side. From AMO's perspective it would basically look like

  1. Do an OAuth flow just like you're doing now, so that you can figure out who the user is.
  2. Look up the user in your db and see if they're a developer who needs 2FA.
  3. Check the results of the flow from (1) to see if they used 2FA the first time; let them in if so.
  4. Otherwise, do another OAuth flow, this time asking FxA to force 2FA on the account (by adding ?arc_values=AAL2 in the query parameters).
  5. Check the results of that flow to ensure that they did in fact use 2FA.

Currently, I believe FxA will prompt the user for their password a second time at step (4), unless they're signed in to Sync in their browser. But we don't need to do that, it's a policy choice on our side that we should be able to figure out how to resolve (ref mozilla/fxa-content-server#5916 (comment) and friends).

@diox if we resolve the prompting-for-the-password-a-second-time problem, would this setup work for you?

@diox

This comment has been minimized.

Member

diox commented Sep 20, 2018

@diox if we resolve the prompting-for-the-password-a-second-time problem, would this setup work for you?

I think so, yes.

@rfk

This comment has been minimized.

Member

rfk commented Sep 20, 2018

@vbudhram @shane-tomlinson ^ something to think about then; this "we always prompt for the password unless you're signed in to sync" thing seems to be coming up fairly regularly.

@vbudhram

This comment has been minimized.

vbudhram commented Sep 20, 2018

Currently, I believe FxA will prompt the user for their password a second time at step (4), unless they're signed in to Sync in their browser.

Over in mozilla/fxa-content-server#6545, I tweaked password prompt so that it shows when requesting TOTP and you already have a sync session, ref.

After step 4 in #732 (comment), we could

  1. Check for existing session
    • No session, redirect login page with error message and setup link
    • Session is already TOTP verified (goto 5)
  2. Check to see if user has TOTP token
    • No token, redirect login page with error message and setup link
  3. Prompt for TOTP code
  4. Redirect to relier
@rfk

This comment has been minimized.

Member

rfk commented Sep 21, 2018

Over in mozilla/fxa-content-server#6545, I tweaked password prompt so that
it shows when requesting TOTP and you already have a sync session, ref.

So IIUC, on the current version of the code, step (4) will always prompt the user for their password a second time, but the ask here is that it never prompts the user for the password (assuming they have a valid sessionToken from the login at step (1)).

I'm curious, what motivated the change you mention, to force the password prompt when TOTP is requested?

@vbudhram

This comment has been minimized.

vbudhram commented Sep 21, 2018

@rfk It was just to keep the code a little simpler. Removing the prompt meant that if user was signed into sync, there would have to be some checks on the client that the session was TOTP verified. I don't believe it is a huge change either way, and I should be able to update mozilla/fxa-content-server#6545 to not prompt.

I'll move mozilla/fxa-content-server#6545 back into WIP in meantime.

@diox

This comment has been minimized.

Member

diox commented Oct 31, 2018

I've started looking at this to understand better where we stand right now, but I have no prior experience with FxA so I'm a little lost & confused.

We're directing the user to the /v1/authorization endpoint, which then ends up calling a predefined callback on our side (receiving the profile info etc). I don't see any mention in the docs of being able to pass acr_values (assuming arc_values above was a typo) to that endpoint (or any other endpoint for that matter), is it just a problem of missing documentation or should we be using a different endpoint ?

@diox

This comment has been minimized.

Member

diox commented Oct 31, 2018

Blindly passed the parameter to the endpoint and it seemed to be working, so it appears it's just a case of missing documentation. I wanted to file a bug but wasn't sure which repos I should be filing it to ?

Anyway after playing with this a little, I think from AMO's perspective we are missing 2 things from FxA side:

  1. When passing the acr_values parameter, it does prevent the login, but the user is a bit stuck if they didn't have 2FA enabled already on their account. They get an error message saying "This request requires two step authentication enabled on your account" linking to the documentation and that's it. Instead, we would need for them to be able to set it up directly in the same flow, so that they would be able to easily get back to AMO (logged in) once they are done.
  2. We need to visit the authorization page twice, since initially we don't know whether the user is going to log in to a developer account or not. When we redirect the user to the authorization page the second time because they didn't use 2FA, they should not need to re-enter their password. I believe this is covered by mozilla/fxa-content-server#6661 ?
@shane-tomlinson

This comment has been minimized.

Member

shane-tomlinson commented Oct 31, 2018

@diox I believe acr_values=AAL2 support was released 2 days ago, sorry about the lack of documentation. You are right that mozilla/fxa-content-server#6661 should cover point 2, I opened mozilla/fxa-content-server#6683 to cover point 1.

@diox

This comment has been minimized.

Member

diox commented Oct 31, 2018

Thanks Shane, no problem about the lack of documentation, I didn't realize it was that fresh :)

@vbudhram

This comment has been minimized.

vbudhram commented Nov 6, 2018

@diox Thanks for giving this a test. Going back to one of your original comments, #732 (comment), are there still plans to do that (or maybe it is done already)?

It seems like it would reduce the overall number of users that would have to do the setup 2FA flow while doing a login flow, if/when it is forced.

When I originally spec out the problem, the setup 2FA flow and login was more complex than I thought, but I can circle back with UX and get a better idea.

@diox

This comment has been minimized.

Member

diox commented Nov 6, 2018

That's a question for @jvillalobos - Jorge, are there any plans to communicate to developers that they can set up 2FA by themselves right now to improve security (without forcing anything on our side just yet) ? As @vbudhram points out it would reduce friction for when we do force it to be enabled later.

@jvillalobos

This comment has been minimized.

Member

jvillalobos commented Nov 6, 2018

Yes, easing developers into this is definitely important, but we need to have a good idea of when we can turn this on so we can include it as part of the communication effort.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment