Can true private messages be implemented?

I’m really saddened by this. How often does this happen and why is it the go to excuse for snooping through pms? pms should be encrypted. Someone should make a plugin called private messages that allows encrypted messaging between users.


I would support such a plugin… It would require users to generate and store private keys though. Of course you can already do this by encrypting your own messages locally and sending them by pasting the encrypted content in. But you could save one step at least.

Problem is, you cannot send your private key to the server, it has to stay on your machine.


And any such functionality should refuse to run if the site is not being served under HTTPS, as otherwise an attacker could inject javascript to cause the private key to be sent to his server.


I would tie this feature to local password authentication.

  1. The user’s asymmetric keypair is created client-side.
  2. The private key is encrypted with with a symmetric algorithm using a key derived from the user’s password (which is validated with the server).
  3. The encrypted private key and unencrypted public key are stored in their profile, the unencrypted private key is cached in browser local storage.
  4. If the user wants to read an encrypted private message but the private key is not available, the whole process is reversed: validate password, receive encrypted private key, derive symmetric key, decrypt private key, cache private key.

That’d require some changes to the password change workflow. Routing user-initiated password changes through the same logic for admin-initiated password resets won’t work; at some point, the user’s encrypted private key, current password and new password must all be present in the client or any password change would destroy the private key and thus any previously received private messages.


Actually, no, I think it’s fine!

When you click Change Password, you get a prompt to “Please unlock your private key.” (skipped if it’s already in unencrypted form), the key is re-encrypted with the new password and uploaded.

You just have to trust that the site admins don’t put in extra javascript to gimp the encryption or steal your key. And we’re back to the original trust anchors.

1 Like

Well, okay. You don’t have to change the workflow, you have to add a step to enter the current password. Same difference, right? :wink:

1 Like

There are quite a few concerns here:


If this is implemented in JS the “true” security of this system depends on no-one interfering with JavaScript payloads. This means HTTPS would be an absolute minimum, however you also can not properly trust browsers due to rogue plugins etcs. So if you want to turn security up to 100 you need another solution.

You should not trust the server

If the server has the password ANYWHERE, including in a logfile somewhere or whatever it can not really be trusted. You can not send passwords to the server, period, instead the login algorithm would need to change to send both an encrypted password and encrypted private key.

This does not solve the conversation problem, how do you allow N people to converse?

Instead, for conversations to work.

  1. The OP contains an encrypted “conversation key” it is encrypted with the public key of every allowed participant.
  2. Each posts raw is encrypted using the conversation key, which can only be obtained by decrypting the OP.

Either that or you simply encrypt every message with the public key of every participant and have rather long and heavy posts

This makes an appealing sell for a “mobile app” or “standalone Discourse” where needed

Only way to totally trust this kind of system is to have a signed binary, that way you eliminate all the variables of running such a system and can correctly audit it.

“Mobile apps” or something like Google ARC or Atom Shell become very appealing. They allow you to have trusted binaries, which is critical.

Best effort security here and security by obscurity are a complete no-go. This kind of system should be usable by political activist without worrying that they can be sent to jail for life.

If we had the funds to build this we would

A project that allows you to mold Discourse into a truly private communication platform is incredibly appealing to me (and @codinghorror) . In the age of mass surveillance the Internet needs a VERY easy to use alternative that provides true privacy.

Hint @downey, guess what else is not private, every email you have on GMail, Snowden revealed that the NSA have a firehose into GMail and so on.

If we had the money at Discourse to throw onto such a project we would at a blink. Its a multi month effort to get it done right, but has a potential of disrupting the status quo and allowing for low-friction private conversations.

However this needs to be done correctly and securely, with zero shortcuts. The server can not be trusted here. Only signed binaries.


Yeah, absolutely.

However, I think that encryption that does rely on the integrity of the site and UA is still useful. At the very least, it raises the hoop an admin must jump through to reveal his users’ private messages and prevents a single rogue admin from grabbing all the data in a single operation; they would need to inject a backdoor and wait for users to reveal their encryption keys, giving other admins an opportunity to detect what’s going on.


Wouldn’t it be possible to extract any client-side JS code that handles passwords, keys and crypto mechanisms and wrap it into an official “Discourse Crypto” companion browser plugin? But where do you stop? For this to be 100% effective, all the UX that deals with passwords and unencrypted messages would have to be moved into the plugin as well… and we’re basically back to the fat client.

… aaaaand I’m rambling again. :confused:

If this is implemented correctly. You will never be able to recover your private key. But you could replace it rendering all older messages unreadable forever. If the server holds any keys for your private key you thusly moot the entire concept. This should be only an option that someone can enable as an administrator but I highly agree that it should be included that would make this literally the best communications platform to date.

You could just sign the page prior to sending the content to the client. Even if we never have this feature. It would be incredible to even simply have a ultra simple design spec document or even a simple video to explain how it would be properly implemented with OpenSource tools of today.

Okay, then you need to be able to publish multiple public keys, and the conversation key needs to be encrypted for all keys of all recipients.

Sign with what key? HTTPS assures that the JavaScript you get is the JavaScript the server sent, but this is about a malicious admin who modifies Discourse to send insecure JavaScript code. If you sign part of the script (which would then need to be distributed pre-packaged, in a “sort of” binary form) with an “official” key owned by the Discourse devs, the site admin could simply remove the signature check or deliver a different public key.

No, effective security that protects against admins must be done outside of the webapp, based on stable, audited code that can’t be modified remotely without the client’s permission – because you absolutely must remove trust in the site admin from the equation.


I would just suggest to people to use WebOfTrust or something to make sure things are as they should be.

1 Like

Web of Trust is a website reputation and review service. (And that’s a straight quotation from their about page.) It has nothing to do with key trust or identity validation. It will not protect you in any way if a site’s admin goes rogue or has their account compromised.

Yeah but its likely the only way you’re going to know if someone is compromising the security of the deployment. Theres really no other way to do this and its likely way beyond the scope of what the developers of Discourse will be doing. If you’re going to shady websites than its your fault if they’re stealing your passwords.

I don’t think we’re talking about the same topic. ¯\_(ツ)_/¯

This is about designing a crypto protocol that allows users of a Discourse site to exchange private messages in a way that will prevent the site’s admin staff from revealing the private message contents. We should assume that the site looks and behaves benign in any way other than that an attacker with a legitimate user account, admin privileges, root-access to the server, motivation and good technological knowledge is trying to read users’ private messages.

Now, how exactly is WoT going to help defeat or reveal this specific attacker? :smiley:

1 Like

What I was referring to.

The problem

#####Bob Alice and Chuck
Alice is the host of a deployed copy of the web app.
Bob is the developer of the web app.
Chuck is the visitor/end user of the web app.

Bob is not going to be able to deploy code securely to Alice’s servers. For example if Bob is giving Alice a deployable copy of his web-app (Discourse), that Bob has gone to great lengths to secure against tampering, listening(MITM) or other exploits. If Alice as the admin of your site tampers with Bob’s code theres no way that the Chuck can trust the code.

Unless Bob can guarantee that the web-app is unmodified from the Bob to Alice’s specific deployment than you’re never going to have this guarantee. If you code signed said crypto stack in some specific way then maybe you could potentially trust it. Realistically you can’t trust crypto that you don’t control which from what I understand is the goal here. What you can do is hope that there are people reviewing websites which you visit for exploits and MITM problems. This is where my suggestion for WOT comes into play because its a third party review site where if you can’t trust a site you report it. Its about as best as you can get. Otherwise I’d be afraid that this would be just a rabbit hole of dependencies and complex problems that this project isn’t intended for.

##Currently available solutions/tools
There are many tools for verifying the authenticity and integrity of a session like Perspectives Calomel SSL Validation Https Everywhere and even something as simple as LastPass which isn’t technically TNO. Basically the words Secure and Hosted are essentially incompatible. The only remaining issue is that basically we don’t want to have to install a bunch of dependency plugins in browsers because the normal users won’t be doing this for only one site.

Yes, which is exactly why, from the start, Sam was requiring signed binaries and I was playing with the idea of having a companion plugin provided by the Discourse devs that contains the sensitive code and UI.

Edit: I should amend this; I did (and still do) consider an imperfect implementation that relies on unmodified code. At the very least, such a feature would protect against wholesale theft of private data.

it could be first implemented in js correctly, and later repackaged, but all the patterns need to be correct from day 1. So you would not send unencrypted passwords to the server, for example.

Keep in mind that many teams of very capable security researchers have worked on this problem, and continue to work on it. It’s not in any way unique to Discourse, although Discourse might add some unusual twists. The general problem of providing end-to-end encrypted communication between two parties without any ability for a party in the middle to access the content (or even metadata about the content, which can also be revealing; witness recent revelations in the Snowden documents), while simultaneously making this tool easy to use and frictionless as possible is a very, very hard problem.


Very true. I think this falls outside of the scope of Discourse. IMO user-to-user messages are just a side-feature of Discourse.

With one of the prior discussions about “private” messages, I added to the forum guidelines of The Seasteading Institute:

Be aware that the forum admins can view all site content, including user-to-user messages.

and posted an administrative announcement notifying the users of the updated guidelines and why.