nextcloud / mail

💌 Mail app for Nextcloud
https://apps.nextcloud.com/apps/mail
GNU Affero General Public License v3.0
842 stars 260 forks source link

[Suggestion] Other way to store password #4277

Open songmeo opened 3 years ago

songmeo commented 3 years ago

Reason: AD passwords are stored in the database encrypted by Nextcloud secret. This is very insecure because if your service is compromised then our AD passwords will also be exposed.

Alternative/Example: Wildduck Webmail uses Authelia/HAproxy to authenticate users from AD and supplies authenticated users' usernames via HTTP Remote-User header to Wildduck API. Webmail and API talk to each other by shared secrets. Therefore, users are provisioned into Wildduck backend without passwords.

ChristophWurst commented 3 years ago

How will that work in background jobs?

songmeo commented 3 years ago

I mean this is a very bad practice. NextCloud might be responsible for organization compromises. Please see this

https://www.vaadata.com/blog/how-to-securely-store-passwords-in-database/

I found something which I think might be useful:

https://stackoverflow.com/questions/5089841/two-way-encryption-i-need-to-store-passwords-that-can-be-retrieved

https://security.stackexchange.com/questions/30193/encrypting-user-data-using-password-and-forgot-my-password

Because of this, we are not using NextCloud Mail anymore so we just want to let you know.

zolfariot commented 3 years ago

I agree that having encrypted or plain-text password in the Nextcloud database is far from best practices. Especially in instance in which Nextcloud, IMAP and other services are all connected to the same password store (possibly hashed). This simple app breaks completely the benefit of storing the password hashed in the main store at the beginning.

Nevertheless, this is the only way for Nexcloud Mail app to access the IMAP server.

I think we should consider two different risks, in case the Nextcloud instance is fully compromised.

1) The attacker will have access to all users IMAP account. --> Unfortunately I think it is impossible to mitigate this risk. The Nextcloud instance is entitled to access the IMAP server (by stored user password or any other means), so the attacker will be entitled as well.

2) The attacker will get easy (without rainbow table/brute-forcing) access to the plain-text password. Once this happen, the attacker can use that password to access to even more critical services within the same domain (LDAP, or AD, or any other). --> I think this is the main risk that should be addressed. It is true that having access to file sharing + mail is already an huge breach. But companies can have many other services connected to the same authentication factors. Also, even if it is not best practice, the user may use the same password on many different websites. Admin may be required to also take into account risks coming from users not applying good password habits.

I thought to several possible approaches, all of them need reconfiguration also at the mail server level: 1- Using one master wildcard password for the mail server (Dovecot for example has this feature). The one master password, used together with any existing user, will grant full access. Nextcloud-Mail is provisioned with the master password for each user (user should be prohibited for reading their own password). Result: attack would result in complete access to the IMAP account, as before, but user password stay safe. 2- Using SAML, OAuth, or another SSO solution. Access token to the IMAP server are acquired by the user from their browser, than forwarded to Nextcloud and stored in the DB. The user can be regularly polled to renew/extend the token validity, or this can be done automatically when the user is browser logged-in. Result: attack would result in complete access to all mail accounts that hold valid token at that time. If the user doesn't use the web interface for a while background syncing (and notifications) will stop, in this case. Again, password are protected.

ChristophWurst commented 3 years ago

Thanks for your input @zolfariot.

The master password approach sounds most reasonable, we already have account provisioning as a feature for enterprise setups, like larger organizations that have the same user back-end for Nextcloud and the email server. We could allow admins to specify a password there.

Regarding SSO: we recently looked into https://github.com/nextcloud/mail/issues/3146 and unfortunately there are some niche standards for that but nothing that seems too widely used or supported in other clients. Correct if I'm wrong but I think this is unfortunately not used much in practice.

Because of this, we are not using NextCloud Mail anymore so we just want to let you know.

Noted.

If anyone has serious concerns about security or thinks that there is a flaw, please be responsible and report this at https://hackerone.com/nextcloud.

Zepmann commented 3 years ago

I agree that having encrypted or plain-text password in the Nextcloud database is far from best practices.

Nevertheless, this is the only way for Nexcloud Mail app to access the IMAP server.

I thought to several possible approaches, all of them need reconfiguration also at the mail server level: 1- Using one master wildcard password for the mail server (Dovecot for example has this feature). The one master password, used together with any existing user, will grant full access. Nextcloud-Mail is provisioned with the master password for each user (user should be prohibited for reading their own password). Result: attack would result in complete access to the IMAP account, as before, but user password stay safe. 2- Using SAML, OAuth, or another SSO solution. Access token to the IMAP server are acquired by the user from their browser, than forwarded to Nextcloud and stored in the DB. The user can be regularly polled to renew/extend the token validity, or this can be done automatically when the user is browser logged-in. Result: attack would result in complete access to all mail accounts that hold valid token at that time. If the user doesn't use the web interface for a while background syncing (and notifications) will stop, in this case. Again, password are protected.

Why do you not consider a third option, at least for Nextcloud and mail servers that use the same backend for user authentication? During Nextcloud login, the user's password is stored in memory and is used by Mail to login when the user starts the application, or maybe even directly after the user has logged in.

I believe Rainloop works like that: store the user's entered password for a successful Nextcloud login in memory (only), and use it to let the user login using Mail.

This would not solve risk 1, but it would mitigate risk 2 somewhat since memory access is also required to access passwords for active user sessions. This might be further mitigated by using the password once during login, and keeping IMAP+SMTP connections open, although this would be quite a dirty solution.

ChristophWurst commented 3 years ago

Why do you not consider a third option, at least for Nextcloud and mail servers that use the same backend for user authentication? During Nextcloud login, the user's password is stored in memory and is used by Mail to login when the user starts the application, or maybe even directly after the user has logged in.

Again, that only works as long as you don't have any background processes, so this comes with functional limitations.

This would not solve risk 1, but it would mitigate risk 2 somewhat since memory access is also required to access passwords for active user sessions. This might be further mitigated by using the password once during login, and keeping IMAP+SMTP connections open, although this would be quite a dirty solution.

Indeed. The server is where an admin could snoop on the password. And they can do that even for a password that is "only" stored in the session.

The constant connection also don't mitigate this, then the admin can get the password when the connection is established. Also technology-wise keeping a connection open is not quite feasible with php.

The only solid solutions I see is either a master password with provisioned accounts (enterprise setups) or any authentication mechanism where you don't give your actual password. Like some services allow you to generate app passwords and if you then use that in Nextcloud Mail you at least do not give it your main password.

stale[bot] commented 2 years ago

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

j-insan3 commented 2 years ago

I think we still need to address this issue. The easiest way to archive something reasonable is by implementing the master password for provisioning accounts.

ChristophWurst commented 2 years ago

sounds reasonable. do you run a larger installation where this would be possible?

rotdrop commented 2 years ago

Why do you not consider a third option, at least for Nextcloud and mail servers that use the same backend for user authentication? During Nextcloud login, the user's password is stored in memory and is used by Mail to login when the user starts the application, or maybe even directly after the user has logged in.

Again, that only works as long as you don't have any background processes, so this comes with functional limitations.

Are background-jobs really a good reason against "better practive"? One could for example trigger jobs from the frontend via AJAX calls. Or use register_shutdown_function() in order to have avoid execution time limits.

Maybe the unauthorized (meaning: no user credentials) NC background-job framework is just not well suited for the kind of background jobs the mail app needs to run.

Of course, if the server is compromised s.t. someone has root-access then any password can be spied out. Still the current state of the mail app leaves a permanent "password-footprint" in the database. This doesn't look like "good practice".

There are also other aspects. Storing the passwords encrypted with just the server-secrete increases the "responsibility-burden" on the admins. Ideally, as sys-admin I do not even want to have the ability to get hold of any user's passphrases. Storing password in more-or-less plain-text (just encrypted with the server secret) just does not "feel right".

ChristophWurst commented 2 years ago

Anyone who has access to the server component and its code could also just change it so it logs the password when it's sent from an ajax call.

That will never change. Even if the app uses other means to authorize on IMAP, the application will have access to this sensitive information unless the front-end talks to IMAP directly.

ChristophWurst commented 2 years ago

XOAUTH2 support looks doable: https://github.com/nextcloud/mail/pull/6819. Only the vender-specific part of acquiring and refreshing tokens is a bit more work.