Feature request: Remove the e-mail field for `new account` page
kerkmann opened this issue · comments
Yes, we do need it, kind of. The reason is security.
The URL is non-guessable, which a lot of people consider being "secure". The problem is, URLs are never encrypted and logged in a lot of places. This means your "secure" URL will just show up in any access and routing logs in any host in between you and the destination. So, either a person or an automated tool could scrape the logs and "use the link before the user can", which can lead to account takeover, if they are just quicker.
For this reason, Rauthy does
- Create a binding cookie once such a page has been opened. This means you cannot open this form anywhere else than this very browser, even if you have not filled out any information.
- Request the E-Mail as kind of a CSRF check. Even if someone would get the "secure" URL as a MITM, they would most probably not know the user's E-Mail address used here. So they could steal the URI and block your request, but not take over your account without knowing the E-Mail.
An alternative would be to request an additional PIN or password which is sent with the E-Mail. I thought requesting the E-Mail itself is a better UX though.
All of this may seem not that big of a deal for a fresh account, but it for sure is for password reset's. Also, if your account has registered passkeys, this E-Mail field will not exist, because the Passkey itself would be the CSRF protection.
Edit:
If you have a better idea though, please let me know. Just removing it would not be secure enough for my taste.
But if the entire email with the url is logged, then the email itself is also logged, or am I missing something? the only place where only the url would be logged and not the email itself is rauthy itself. If rauthy itself is not logging it, then the email doesn't matter. Because if the attacker can see the body of the mail, the attacker already knows the email as well. :)
But the email is not in the URL. The user is referenced by user id there, not by email.
Ahhh... Now I understand it, that makes sense. I thought the logs between the server and the email send is compromised and not by opening the link from the mail client. Okay, that makes sense. Hmm.. Right now I have not a better idea, I'll think about it and let you know if I have a better idea. If You/Me or someone else doesn't find a better idea, then this issue can be closed. I'll think about it over night. :)
I thought a lot about the best solution for this and after talking to a few people about it, the email came out as being the best UX without giving up more security. This is a compromise though. The safest way would be to have another dedicated channel to send some 2FA token, or at least a PIN inside the email. Security does not come for free after all.
If your email provider is bad though, you're screwed anyway. They know everything about you and the email content, so they could simply take over anything.
.. by opening the link from the mail client
Yes that's the problematic part. For instance, Microsoft does reaaaally bad things to their users in the cloud. There were users in the past which were using outlook 365 via the cloud for their emails. They never were able to use the provided link, because they always received the answer, that it was invalid. The reason was a bit shocking:
The Microsoft servers did not only scan the email content (like almost all others do as well anyway), but they were actually using, following and scanning each single link contained in these emails. This means that they used the one-time-link for setting the user's password inside which would make it unavailable for the users themselves.
This is the only reason why the UNSAFE_NO_RESET_BINDING
config variable exists after all.
Thanks @sebadob for the conclusion. Yes, that's right. Security comes sometimes with stuff like that. One thing I would like to discuss is, should this be configurable? For "newer people" it can be annoying to be that restricted. I can understand the security aspect, but spoken from other systems, it's quite uncommon (spoken from keycloak, okta, authentik, yadda yadda yadda}. Is there a way to loosen that rule? The idea would be to have a boolean flag in the config to allow password set without typing their email. wdyt? :)
Well, since we do know now if this is a reset or a set for a fresh account, we could actually get rid of this for new accounts. That would make sense and not even be too harsh for the security, since a fresh account usually does not have any access yet, before it is set up anyway.
The mechanisms to do this do already exist in both backend and frontend. When a user has an active passkey, the email is actually inserted into the HTML during SSR. This means the only thing we need to add during SSR is a check, if this is a fresh account and then pre-render the E-Mail.
We could do this globally by default. Would you like to submit a PR for that? Otherwise I can take a look, but probably not today.
I decided to get rid of the email input completely and make it maybe opt-in, if at all.
The security will not be affected too much, since it could become a problem when you are in a network with deep packet inspection and where proxies terminate TLS early, but this does not apply to most of the users at all, and only then it could be an issue if such a proxy is vulnerable or has an evil admin.
The UX would benfit a lot though when we just get rid of the email input and make the binding-cookie opt-in. This way we can keep the (almost paranoid) level of security, but the default is more approachable.
Yes, I am happy to hear that news, awesome! ❤️