BypassTowFactor in SignInManager:ExternalLoginSignInAsync should default to False #2067
Comments
Exactly, that is how I implemented it in my UI customization |
If you are using external providers we expect the 2fa enforcement to be their concern, not that of your app. |
@blowdart |
2fa in that regard is for when they use the app specific username and password, not for when they authenticate via social logins. |
There are two issues with this. The second issue is that the code currently does not work that way.
In the above code, result.Succeeded returns false if my app wants 2fa to be checked (cookie expired). So I think @wijnsema is correct to suggest that the code needs to check on result.RequiresTwoFactor. |
From a theoretical point of view, I agree with you. In practice, with social providers like Facebook and Twitter the 2fa from the app can be a welcome extra security layer. Like mentioned before: As a developer using Identity I was surprised to see 2fa not working with external login. But I understand your explanation. |
Well what if someone added 2fa to facebook already? Do people really expect two 2fa prompts? I think 4fa might be an unwelcome shock :) |
That would be a rare case where both 2fa cookies are expired at the same time, but yes, I would expect that.
In any case, the current code does not work, as it does not log the user in at all, when the 2fa cookie is expired.
From: Barry Dorrans <notifications@github.com>
Sent: maandag 19 november 2018 15:08
To: aspnet/Identity <Identity@noreply.github.com>
Cc: Pieter van Kampen <pieter@datec.nl>; Comment <comment@noreply.github.com>
Subject: Re: [aspnet/Identity] BypassTowFactor in SignInManager:ExternalLoginSignInAsync should default to False (#2067)
Well what if someone added 2fa to facebook already? Do people really expect two 2fa prompts? I think 4fa might be an unwelcome shock :)
—
You are receiving this because you commented.
Reply to this email directly, view it on GitHub<#2067 (comment)>, or mute the thread<https://github.com/notifications/unsubscribe-auth/APQtQ2QYELusfhEmUDZvW0-d6SlbQXvnks5uwrsrgaJpZM4Yd9OL>.
|
Maybe not a big problem.
|
The code bug is a bug, @HaoK can you look at that? I'd respectfully disagree on the idea that "you expect 2FA to work for both local and external login", as that's not how it's designed, and to be honest it's not something I've seen in the wild, so this would be something the templates wouldn't support without you changing the flow as you have, |
We then agree to disagree. I remain that if someone put’s social media logins on their site, social media logins should not enable someone to bypass the 2fa that you have set on that site. If someone hacks your PC and steals both your sensitive app’s credentials and your social media credentials, you still should be able to trust the 2fa that you have set on the sensitive app.
Put it the other way, for GDPR, 2fa helps me to prove that the user logged in, rather than some hacker, in case of a data leak. With your preferred implementation, it proves nothing, as I cannot check if someone has also protected their social media accounts. In that case, I need to take that possibility of my app altogether.
In my view, the code is not a bug, the UI has a bug.
|
Yes, I accept its a scenario that would work for you, but templates are starter points which cover the common cases, hence saying it's not suitable for the templates themselves. |
That is fine with me, but if you change the output of ExternalLoginSignInAsync to return true where it now returns false for 2fa, it would break my code, and disable my scenario.
|
I suggest you change the template to:
Than nothing breaks |
Indeed it's a matter of opinion, I was merely stating my expectations. Maybe this discussion is popping up in the future and then we can look at it with a little more statistics at hand. For now I'm OK with this, good to see the bug is being fixed! |
@vankampenp be careful not overrate 2fa as 'prove' of a users identity. 2fa is just an extra layer. 2fa is as secure as the generated key used to set it up. If this key is leaked somehow (it is not stored encrypted in the default implementations) anybody with this key can bypass 2fa easily. |
True, if you really wanted proof you'd go for certificates, but even those aren't foolproof. |
@wijnsema thanks for the tip!. If someone gets the contents of my database, I have a whole other problem. In the end nothing is secure. But it helps me to think that this extra layer prevents someone to guess a password, or reuse a password written on paper or something like that. At least the hacker will need access to the mobile phone as well (or my database, but than they are no longer interested in bypassing the 2fa). |
@blowdart what code bug are you specifically referring to in here, there's a lot of comments and its not clear to me what behavior is the bug |
The bit where people say there's a bug :D var result = await _signInManager.ExternalLoginSignInAsync(info.LoginProvider,
info.ProviderKey, isPersistent: false, bypassTwoFactor: true);
if (result.Succeeded)
{
_logger.LogInformation("{Name} logged in with {LoginProvider} provider.",
info.Principal.Identity.Name, info.LoginProvider);
return LocalRedirect(returnUrl);
} In the above code, result.Succeeded returns false if my app wants 2fa to be checked (cookie expired). So I think @wijnsema is correct to suggest that the code needs to check on result.RequiresTwoFactor. |
@HaoK I'm not sure this is actually a bug. Maybe @vankampenp can clarify. From my perspective: The code then tries to register a new user, which fails because the user already exists! If you add
just like in Login.cshtml.cs you are redirected to the 2fa page as expected. If you have bypassTwoFactor = true these lines have no influence. So yes, you could call this dead code, but it is very convenient for those who change the bypassTwoFactor while not harming those who leave it as is. |
Yeah that's what I thought, its not really a bug, if this code was still in the template, it makes more sense to change, but since users will need to scaffold and modify the code anyways, they can add that additional 2fa redirect logic after scaffolding, I'm not sure it really make sense for us to add dead code in the library. @ajcvickers @blowdart thoughts? |
Taking one step back, it wouldn't be dead code if the default would be to have 2fa for external logins... |
@HaoK Even though the code is not in the template, given that we tell people to scaffold the code into their applications, it effectively becomes the same as code in the template. Therefore I think we should fix this. 3.0 is fine. |
Leaning towards this not being a bug, we don't want two two factor challenges. Scaffolding out and changing the code is the way to go. |
As requested by @brockallen in #850 it is now possible to bypass 2FA in case of an external login.
I'm sure there are good reasons to bypass 2FA, however the current implementation is far to general:
This bypass of 2FA really needs more refinement.
What makes this really a problem is the fact that it is enabled in the UI templates!
As a developer using the template and enabling 2FA you expect 2FA to work for both local and external login!
Furthermore, the redirect to the 2FA page is missing, so changing to call to
bypassTwoFactor = false
results in a confusing error that the user already exists.In my opinion the following fragment from ExternalLogin.cshtml.cs
should be replaced with
If you enabled bypassTwoFactor it will still work.
The text was updated successfully, but these errors were encountered: