What to do if your Discourse is compromised

We’ve recently had two reports of Discourse sites that were compromised, likely due to weak admin account passwords. So we’d like to document:

  • what to do when compromise happens
  • what we can do to better prevent this in the future

The Database

Please note that Discourse, for several years now, has the following protections in place around the site database:

  • Full database backup download links will only be sent via valid email of a site administrator, so you can’t just log in (via shoulder surfing, or forgetting to log out), you must also control the email address of a site administrator. And you have 2FA set up for your email, right? :wink:

  • To change staff email, you must verify control of both the old and new email addresses – whereas a normal user only needs to verify control of the new email address. This makes it much more difficult to change the email address of a staff member.

  • Assuming you have configured the geolocation database API key (it is free, requires a signup), then you get actively warned when staff members log in from locations that are physically far away from where they last logged in.

  • Admins who have not logged in for over a year are required to re-validate their email address, to reduce attack surface. The site setting for this is invalidate inactive admin email after days and it defaults to 365.

:warning: Still, in case of compromise, you should always assume that a rogue admin account has downloaded a full copy of the site database / backup.

Thus, you should IMMEDIATELY reset all account passwords using the following command:

./launcher enter app
rails r 'User.update_all(password_hash: SecureRandom.hex * 2)'

Additionally you must log out all users

./launcher enter app
rails r 'UserAuthToken.destroy_all'

Finally you must remove all API keys

./launcher enter app
rails r 'UserApiKey.destroy_all' 
rails r 'ApiKey.destroy_all'

Account Passwords in the Database

Per our security doc, Discourse uses very strong, slow to attack hashes on passwords stored in the database:

Discourse uses the PBKDF2 algorithm to encrypt salted passwords. This algorithm is blessed by NIST. Security experts on the web tend to agree that PBKDF2 is a secure choice.

And the minimum default password length is 10 for users, and 15 for staff (as of June 2021) – so this makes it difficult to brute force reverse the password hashes to get the hash. But that doesn’t prevent users from setting a password of password1password1 or something else that is trivial to reverse, even with a strong hash.

Emails in the Database

The attacker can see all email addresses for all users on your site. This is normally privileged info that even moderators have to click a button to reveal.

Message Content in the Database

Since the attacker has a copy of the database, they can see all information stored in all posts.

  • If you have external passwords or account info relayed in your replies, private or public, you should change those passwords immediately.

  • If you have sensitive information in your replies, private or public, be aware that the attacker can see that information.

Encrypted messages

If you are using the Discourse Encrypt plugin, encrypted messages will be end-to-end encrypted. This means that if a database leaks, the attacker will not be able to gain access to content in encrypted messages.

Regulations

Be sure to seek professional legal advice as to your legal requirement. Certain regulations such as the GDPR and CCPA may mandate disclosure.

In the Future

You may wish to require two factor authentication for staff users if you have reason to believe your site will be under attack. The site setting you want is “enforce second factor”

enforce second factor

Forces users to enable two-factor authentication. Select ‘all’ to enforce it to all users. Select ‘staff’ to enforce it to staff users only.

43 Likes