Skip to content

Two factor authentication#7751

Merged
jhass merged 24 commits intodiaspora:developfrom
lislis:4299-2fa
Apr 28, 2019
Merged

Two factor authentication#7751
jhass merged 24 commits intodiaspora:developfrom
lislis:4299-2fa

Conversation

@lislis
Copy link
Copy Markdown
Contributor

@lislis lislis commented Mar 26, 2018

Hey there!
This is my attempt to implement 2fa, ticket #4299

I know, there are no tests (:see_no_evil:), all strings are hardcoded, and the UI is far from 'done' but I'm at a point where I need some feedback on the general direction.

Some screenshots:

New link on the settings page, 2fa deactivated
screenshot-2018-3-26 two factor

Scan the code and confirm
screenshot-2018-3-26 two factor 1

Confirmation and backup codes
screenshot-2018-3-26 two factor 2

Settings page, 2fa activated
screenshot-2018-3-26 two factor 3

After sign-in, prompt for token
screenshot-2018-3-26 diaspora - sign in

And that is it so far.

Missing:

  • tests!
  • put copy from templates into translation files
  • fix UI

and anything else that's missing

Comment thread app/controllers/sessions_controller.rb Outdated
Comment thread app/controllers/sessions_controller.rb Outdated
Comment thread app/controllers/sessions_controller.rb Outdated
Comment thread app/views/two_factor_authentications/_confirm.haml Outdated
Copy link
Copy Markdown
Member

@Flaburgan Flaburgan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

First of all, thank you very much for working on this. The flow looks good in my opinion, no global blocking points, so you should be able to continue that way and polish your work.

Two remarks:

  • I don't see where the hashing algorithm is set. Can you assure it's a modern one, not SHA1 which was the default some years ago?
  • I'm a bit afraid of the support load this new feature can bring. Framasphere moderators are already spending a lot of time with users who lost access to their account (that's why we have feature requests like #7442). The question is, is 2FA added to protect users from a stolen password (if so, then when resetting the password by e-mail, the 2FA code should not be asked) or is it also aimed to protect them if their email gets compromised, like you did here. (In that case, you're in trouble anyway but eh, that's in part why 2FA has been built), At least the podmin should be able to access recovery code easily I guess, as we will probably be asked them a lot...

Comment thread app/views/two_factor_authentications/_confirm.haml Outdated
Comment thread app/views/users/_edit.haml Outdated
Comment thread .ruby-version Outdated
Comment thread Gemfile.lock Outdated
Comment thread app/models/user.rb Outdated
@SuperTux88
Copy link
Copy Markdown
Member

  • I don't see where the hashing algorithm is set. Can you assure it's a modern one, not SHA1 which was the default some years ago?

It's not hashing, it's encryption, but see #7751 (comment) for more information about that topic.

  • I'm a bit afraid of the support load this new feature can bring. Framasphere moderators are already spending a lot of time with users who lost access to their account (that's why we have feature requests like Add possibility to edit users e-mail address in the admin panel #7442). The question is, is 2FA added to protect users from a stolen password (if so, then when resetting the password by e-mail, the 2FA code should not be asked) or is it also aimed to protect them if their email gets compromised, like you did here. (In that case, you're in trouble anyway but eh, that's in part why 2FA has been built), At least the podmin should be able to access recovery code easily I guess, as we will probably be asked them a lot...

Yes, probably some users will try to ask you to reset their 2fa, but you shouldn't reset it, otherwise 2fa is completely useless. It is optional (so everybody activating it should be aware of this) and there are backup keys (and they are there for a reason). If people lose their 2fa secret and their backup keys, they can create a new account. There is no (official) possibility to reset 2fa if you lost it (there is no "forgot 2fa" similar to the "forgot password", obviously you as a podmin can reset your 2fa if you want, but you shouldn't do that for other users you don't know personally). So you can just create a default answer for everybody asking to reset their 2fa and tell them that it isn't possible and they should create an new account and next time backup their backup keys.

(personally I already see setting another mail-address as critical, when you can't verify if it's the real owner of the account, and the mail-address is the only way to do this. But that's another topic.)

@lislis
Copy link
Copy Markdown
Contributor Author

lislis commented Mar 27, 2018

Thanks for the comments so far <3 I'll look into updating the PR this weekend!

Copy link
Copy Markdown
Member

@jhass jhass left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

On a good way!

Comment thread Gemfile Outdated
Comment thread app/controllers/sessions_controller.rb Outdated
@denschub
Copy link
Copy Markdown
Member

denschub commented Apr 2, 2018

The question is, is 2FA added to protect users from a stolen password (if so, then when resetting the password by e-mail, the 2FA code should not be asked) or is it also aimed to protect them if their email gets compromised

That really doens't matter. If you have forgotten your password, you can reset it, and you can get a new one via email. It doesn't matter if we ask for a 2fa token or not (and in fact, the industry standard is not to ask, because it's kinda pointless). In any case, resetting the password does not reset the 2fa token, and it should not. So even if your eMail address is somehow borked and someone manages to reset the password, there is still no way to get into the account, which is the point of 2fa.

As @SuperTux88 already outlined, there is no way to reset/disable 2fa without a valid TOTP, and there shouldn't be one. Now, there is a risk of someone losing their phone (which generates the TOTP) without having a backup, and that's bad. Like most large applications supporting 2fa, we should generate some backup tokens for users to store in a secret place (like a password manager) to be used as a valid token if they lost their generator. The gem used here has built-in support for this, and we should expose that.

If people enable 2fa, but fail to backup their keys and the recovery key, they'll have a hard (read: impossible) time to get their account back. This is by design. And this is just the way it works here on GitHub as well: If you cannot use the provided validation schemes, you are goofed, the support will not reset your account. Neither will Google, fwiw.

Besides me rambling around... @lislis, thanks for working on this!

Comment thread app/views/two_factor_authentications/_confirm.haml Outdated
Comment thread app/controllers/sessions_controller.rb Outdated
Comment thread app/models/user.rb Outdated
Comment thread config/routes.rb Outdated
@lislis
Copy link
Copy Markdown
Contributor Author

lislis commented May 7, 2018

Update: found some time to work on this again.

Here the current state of the UI:

screenshot-2018-5-6 two factor authentication
screenshot-2018-5-7 confirm activation
screenshot-2018-5-7 two factor authentication recovery codes
screenshot-2018-5-7 diaspora - two factor authentication

screenshot-2018-5-7 two factor authentication 1

@Flaburgan
Copy link
Copy Markdown
Member

It looks very nice, awesome work! Is there a screen where the user can enter the recovery codes too?

@lislis
Copy link
Copy Markdown
Contributor Author

lislis commented May 8, 2018

Recovery codes would go in the same form.
Where I just noticed that that means the input can't be of type=number 😅
But yeah, the placeholder is maybe a bit confusing in this regard. I think I can add text like Can't access your authentication app? Use a recovery code to log in instead. Wdyt?

Comment thread app/views/two_factor_authentications/_confirm.haml Outdated
Comment thread app/views/two_factor_authentications/_deactivate.haml Outdated
Comment thread app/models/user.rb Outdated
Comment thread app/models/user.rb Outdated
Comment thread config/initializers/twofa_encryption_key.rb Outdated
Comment thread lib/tasks/generate_2fa_encription_key.rake Outdated
Comment thread lib/tasks/generate_2fa_encription_key.rake Outdated
Copy link
Copy Markdown
Member

@jhass jhass left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry for the delayed review. Looking very good, I think the below are the last things we need here :)

Comment thread app/controllers/sessions_controller.rb Outdated
Comment thread config/initializers/twofa_encryption_key.rb Outdated
Comment thread lib/tasks/generate_2fa_encription_key.rake
Comment thread lib/configuration_methods.rb Outdated
Comment thread lib/configuration_methods.rb Outdated
Comment thread lib/configuration_methods.rb Outdated
Comment thread lib/configuration_methods.rb Outdated
Comment thread lib/tasks/generate_2fa_encription_key.rake Outdated
@lislis
Copy link
Copy Markdown
Contributor Author

lislis commented Oct 25, 2018

@jhass there is still a problem in Travis where it can't find the twofa_encryption_key. How should I deal with that?

Comment thread app/models/user.rb Outdated
Comment thread lib/configuration_methods.rb Outdated
Comment thread lib/configuration_methods.rb Outdated
@jhass jhass requested a review from Flaburgan October 25, 2018 13:33
@lislis
Copy link
Copy Markdown
Contributor Author

lislis commented Oct 25, 2018

Ah, the cucumber test for resetting passwords is outdated.
With 2fa coming, you won't be logged in automatically anymore after resetting the password since that would bypass the second factor. Instead after typing your new password, you just have to manually sign in with your new password.
I'll look into updating the cucumber test

Comment thread Gemfile.lock
@jhass jhass requested a review from Flaburgan April 28, 2019 09:38
Copy link
Copy Markdown
Member

@Flaburgan Flaburgan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Two minor remarks, and maybe a bug with the disabling and recovery code? I don't know what's going on there as this is covered by the tests... Otherwise it works very well! This should be integrated soon ;)

Comment thread features/step_definitions/two_factor_steps.rb

.col-md-6
%p= t("two_factor_auth.confirm.manual_explanation")
%pre.well= current_user.otp_secret.scan(/.{4}/).join(" ")
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I successfully activated OTP with the code but first did the mistake to enter the space displayed inside the secret here. Can we indicate somewhere that those are only for readability and not actually part of the secret?

Comment thread app/views/two_factor_authentications/_deactivate.haml
@jhass jhass requested a review from Flaburgan April 28, 2019 16:17
Copy link
Copy Markdown
Member

@Flaburgan Flaburgan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ship it!

@jhass jhass merged commit 1da1187 into diaspora:develop Apr 28, 2019
@jhass
Copy link
Copy Markdown
Member

jhass commented Apr 28, 2019

🎉 🍪 🎊

@SuperTux88
Copy link
Copy Markdown
Member

Great that this is finally finished 🎉 🍪

@jhass you didn't add a changelog entry when you merged this, but I'm sure we all agree that this deserves one ;) But this leads me to the question: do we want to uplift that to the next-minor branch? @Flaburgan marked this with the 0.8.0.0 milestone a while ago, but I don't know why? I know this contains a migration to add the required columns to the user table, but I think that is small enough to be run in a minor upgrade? Are there other reasons to not add this to the next-minor? Do we want to test that on develop pods first?

@jhass
Copy link
Copy Markdown
Member

jhass commented Apr 28, 2019

🤦‍♂ I knew using Github's squash merge was going to be too easy...

I'm fine with uplifting this to next-minor, in fact I'll do it right away.

@jhass jhass modified the milestones: 0.8.0.0, 0.7.11.0 Apr 28, 2019
jhass pushed a commit that referenced this pull request Apr 28, 2019
@lislis
Copy link
Copy Markdown
Contributor Author

lislis commented Apr 29, 2019

Thank you for finishing this!
🍪 for everyone!

@lislis lislis deleted the 4299-2fa branch April 29, 2019 09:11
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

10 participants