At its heart, this is a password reuse problem.
In 2012, hackers were able to gain unauthorized access to LinkedIn’s database and downloaded password hashes (SHA-1) from 6.5 million user accounts, (the password hashes became public in 2016).
Using a rainbow table, an attacker was able to guess login credentials of a user who used the same credentials for his GitHub account . Being able to login to the GitHub account, the attacker used the OAuth login to gain access to the forum account.
Still, it is worth thinking through all the steps here to consider what could have been done at each stage, and what Discourse / Forum Admins / Users can do to mitigate an attack like this:
-
LinkedIn is breached and used crappy password hashes, which are easy to reverse (turn the hash back into a password string)
Software developers: stop using crappy password hashes in your software. Discourse uses strong hashes.
-
User has same email/password on LinkedIn as GitHub
Users: don’t re-use login credentials on multiple sites! Instead, use a password manager or otherwise generate unique passwords for every site you visit.
-
Hacker takes email/pass credentials from LinkedIn and uses them on GitHub where they also work
Users: turn on two factor auth EVERYWHERE, including GitHub!
-
The Discourse forum has multiple login methods configured, user/pass as well as GitHub social logins. Since social logins are equivalent to user/pass… bam the hacker is now in as an admin on Discourse.
Forum admin: don’t allow social logins? This is not a real solution, honestly, but that’s all I can think of for this step. If your site is super security conscious then you’d need to provide only one method of login rather than 4-5. I’m not aware of any way Discourse could enforce 2FA requirements for third party social logins; Discourse can only enforce 2FA on Discourse logins.
-
The hacker is logged in as an admin (this is very bad) and now needs to download the Discourse database. Except… an admin login alone is not sufficient; Discourse requires email access to get the emailed download token for the Discourse database. So yay! protected, right?
But… here’s where it gets interesting:
the attacker edited the forums email templates and forced the forum to send out a fake message stating that the forums backup job failed, in order to trick another administrative user and change his mail address.
Based on this message the backup job was started manually by the ownCloud admin team to test and resolve the alleged error. After the backup was finished successfully, we assumed a minor hiccup was now resolved. Unfortunately, one of the recipients fell for the classic phishing attack allowing the attacker to take over another administrative account. By changing the accounts’ email address to a attackers’ controlled one he succeeded in his attack and gained access to a fresh backup of the forums database.
Please note that this is technically already mitigated
Discourse staff email address changes require confirmation via email on both the OLD and NEW email addresses.
However
the hacker edited the staff old email confirmation template, so that it included the “yes, validate this old email change” URL and then once this was sent to the old email address and clicked, the hacker suddenly had permission to change the old email address to a new one he controls
Bear in mind this is a very sophisticated, in-depth attack, and it could have been stopped many levels above with practices that are already strongly recommended, just read through the lightbulb callouts above.
Still, we believe strongly in being safe by default at Discourse, and we think there is more we can do after closely analyzing this story. As a result, we just implemented a change such that nobody, not even an admin, can modify that particular email template. We believe it is a rare case, but worth addressing, because:
-
this particular email template is only ever sent to staff on email change, as both the old and new email addresses must be confirmed. For a regular user only the new email address needs to be confirmed. So changing this template for cosmetic design reasons would only be seen by staff, never by regular users, and is thus unimportant.
-
the risk of allowing admins to change this template is too high, as illustrated by the above REAL WORLD story which actually happened, and was the critical step that allowed the attacker access to the complete Discourse database.
Also, before commenting on this story, a few other things you should know:
-
Enabling 2FA (two factor auth) in Discourse logins automatically disables all social logins.
-
It is definitely possible to have 2FA login enabled through Google, Github, and other social logins, but I’m not aware of any way Discourse could enforce that, or know about it.
-
We don’t yet have the ability to print paper backup codes for Discourse 2FA but that is slated for 2.1.
-
it’s worth thinking about what one logged-in admin can do to another admin’s account. Email changes through the web UI, for example, have to be verified on both new and old email addresses no matter who initiates the email change, so that is safe. Demoting a user from admin to regular user is a potential workaround – but granting admin to another account requires email confirmation via the current admin email address. Gotcha!