OAuth-based login: Disable account merging

(Ralf Jung) #1

I’d like to make a feature request: It would be great if it was possible to disable the automatic merging of accounts when logging in with OAuth that happens right now. Concretely, if I create a local account, and then later, I want to log in via GitHub to this account (local and GitHub account have the same email address), this should not work unless I first connect those two accounts.

The reason I am asking is security concerns: With the automatic merging as it is implemented right now, any broken or dishonest OAuth provider can take over any Discourse account. For example, if GitHub would respond with incorrect email information, saying that some random account foo has my email address - this could happen either because something in GitHub is broken and they screwed up email verification, or because they became malicious, or because they were forced to do so by whatever means - then the owner of foo could log in to Discourse as me, getting full admin privileges in my local installation.

GitLab shows how OAuth logins can be implemented without trusting that OAuth providers provide correct e-mail addresses: If I want to log in with GitHub to a locally created account, I first have to log in locally, and then “connect” the two accounts in my GitLab settings. This successfully prevents account take-over even if OAuth provides incorrect email addresses. So, with GitLab, only those users that actually use GitHub to log in have to trust GitHub not to misbehave. Whereas, with Discourse, every single user of a Discourse instance has to trust every single OAuth provider accepted by that instance.

(Sam Saffron) #2

Not really, if you are to trust emails for a provider you have to flag it explicitly.

If an authenticator does not set email_valid well the email is not trusted and no lookup by email happens.

(Ralf Jung) #3

If I read that code correctly, the GitHub authenticator just trusts GitHub to correctly state whether the mail is verified, and hence it is vulnerable to the attack I described? I have hardly any Ruby experience, so I may be reading this wrong.
All I did is configure the GitHub token in the admin settings. I have no way to configure whether these mails count as verified, or not. In this situation, what prevents broken or malicious GitHub from taking over any account?

So let’s assume I patched that file so that the email never counts are verified. How do I connect an existing local account to a GitHub account?

(Sam Saffron) #4

GitHub returns special information in the OAuth payload to notify us that it verified the Email. Meaning that it knows for sure that the Email is good.

You can’t just plug in any Email in GitHub (go ahead … try), granted if GitHub is somehow hacked or exploited we would be vulnerable, but if you are tinfoiling this much I would recommend disabling OAuth altogether.

(Ralf Jung) #5

It is possible, with reasonable effort, to use OAuth without trusting that a third-party correctly verifies emails. GitLab shows how to do it. This is an application of the principle of least privilege, which says that no party or process should ever be granted more privileges than are absolutely necessary for it to function. Also see Wikipedia.

But I take it security concerns are considered “tinfoiling” here, and if I want security, I should disable Discourse alltogether. OAuth-based logins is a nice example where the trade-off between security and comfort can (in principle) be made by every individual user. Why do you turn this into a side-wide trade-off (no comfort for anybody, or reduced security for everybody) without any need?

(Sam Saffron) #6

If people are able to forge emails in the oauth payload they are also able to exploit the Github user id there, thus log in to any user account that authenticates with Github

Regardless you can write a plugin to provide you with whatever policy you wish

What you are describing is not exploitable short of getting access to Githubs side of the oauth end