ory / kratos

The most scalable and customizable identity server on the market. Replace your Homegrown, Auth0, Okta, Firebase with better UX and DX. Has all the tablestakes: Passkeys, Social Sign In, Multi-Factor Auth, SMS, SAML, TOTP, and more. Written in Go, cloud native, headless, API-first. Available as a service on Ory Network and for self-hosters.
https://www.ory.sh/?utm_source=github&utm_medium=banner&utm_campaign=kratos
Apache License 2.0
11.24k stars 963 forks source link

Replace magic links with TOTP OOB codes #1451

Closed aeneasr closed 2 years ago

aeneasr commented 3 years ago

Is your feature request related to a problem? Please describe.

As we've seen in several issues #1202 #1142 the current link strategy is flawed because email clients with antivirus open the link and invalidate the token.

Describe the solution you'd like

Instead of relying on links we should use recovery / verification codes (TOTP) which have enough entropy to avoid distributed brute force attacks meaning at least a 8 char alphanumeric password.

This strategy would deprecate and eventually fully replace the current link strategy.

Describe alternatives you've considered

Resolving this issue in the link strategy is difficult because we need workarounds like UA detection. Antiviruses probably spoof this UA to avoid detection, making it a cat-and-mouse game.

aeneasr commented 3 years ago

Other references I've found:

So in general I think the approach outlined here is superior, even if the user experience is a bit worse (copy/pasting the code). However, this allows us to have the code work cross-device and also in native mobile apps.

zepatrik commented 3 years ago

Is there any drawback of having the link in the email contain the recovery code in the query? This way the UI can prefill the input if it wants to. The code can still be used outside of that use case and manually copied/typed. We even don't need "native" Kratos support (and can't even prevent that practice), as the email template may choose to add the code to the URL. We should instead add best-practice guidance to the docs.

aeneasr commented 3 years ago

The problem would be that people could accidentally copy/paste the URL with the code which would allow someone to take over your account.

zepatrik commented 3 years ago

Then we should definitely point that out in the docs and advise against doing that in the email templates.

ysaakpr commented 3 years ago

We want phone number + otp login as quickly as possible, and can contribute if there is any design or implementation clarity exist. Otherwise we would go ahead modifying the code in according to our requirement, and later plan to use whenever this feature available from kratos

Any thoughts?

aeneasr commented 3 years ago

So for OTP you would need to implement such a strategy analogous to e.g. the password strategy.

You could probably re-use some things from https://github.com/ory/kratos/tree/master/selfservice/strategy/link for this.

Regarding SMS, you would need to extend https://github.com/ory/kratos/tree/master/courier to support SMS using either a well-known service provider (e.g. twilio) or some abstraction (e.g. HTTP RPC call).

I hope this helps. Before you start implementing, I think it would be great to write down your ideas and discuss them as that will save you a lot of time and thought :)

pradyuman commented 3 years ago

Is there a way to mark an email as verified using the admin API? We're building our own (temporary) workaround since a significant portion of our customer base is running into trouble here.

aeneasr commented 3 years ago

Unfortunately there is currently no such way using an API endpoint but the feature (setting verification as an admin) is definitely something we want. If you're up for contributions, that would be a good issue! But before starting implementation, please discuss your API proposal in an issue first :)

NikPaushkin commented 3 years ago

Imo, API endpoint should have higher priority over the out-of-the-box flow solution since it gives you an ability to create your own flow at least.

aeneasr commented 3 years ago

Feel free to come up with a plan for contributing such a feature!

mitar commented 2 years ago

I was also surprised to notice that it is enough just to open a verification link to be verified. But I am also now surprised to read this issue. I mean, why reimplement now everything when the solution is simple: just instead of verifying the account on opening, show a button which user has to click to verify the account? So the link opening is GET, you do not verify the account. If you get POST on the link, you verify the account. You can put CSRF in the mix if you want, and this is it.

I think that having additional/other strategies for verification and recovery could be nice, but I think we should first make a simple fix now for this and iterate later. So simple fix is:

aeneasr commented 2 years ago

I haven't updated the original issue, the idea is to do exactly that for link strategies! So 100% agree.

Still, "codes" are much better because they work across devices and can work with native apps as well, whereas links always open in the browser.

mitar commented 2 years ago

Awesome. I agree.

Still, "codes" are much better because they work across devices and can work with native apps as well, whereas links always open in the browser.

Yes, once there is "redirect to app to show button to click" for link strategy, it is easy to extend that with "show the input form for the code" for code strategy. But first step is to have the app involved at all.

Does triage to the next release for this (0.9.0) still holds?

aeneasr commented 2 years ago

Does triage to the next release for this (0.9.0) still holds?

Hopefully 😬

sebmellen commented 2 years ago

Any update/progress on this?

jonas-jonas commented 2 years ago

@sebmellen yes, still working on it. But just cleaning up a few test cases for now. See #2645 for more details.

kszafran commented 2 years ago

@jonas-jonas I have a question about your PR. Will it be possible to combine the magic link with the code in one email? This way users without email scanning software could simply click on a link, while others could fall back on the code.

jonas-jonas commented 2 years ago

This is not planned, no.

The issue would still be that there is a link in the email and the virus scanner would still open the link, thus completing the recovery flow. So even if this user would then go ahead and enter the code, the recovery flow itself is already completed. So the user would still not have a way of completing the recovery, e.g. re-setting their password.