Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Proposal for improving private toot security #4208

Closed
Gargron opened this issue Jul 15, 2017 · 6 comments

Comments

@Gargron
Copy link
Member

commented Jul 15, 2017

Elaborating on #4205 (comment)

Problem description: When a private toot lands on a non-Mastodon server, that server handles it like a public toot. When does this happen? When a Mastodon user has non-Mastodon followers (GNU social, Friendica) and uses the private toot feature. Mastodon users and users of other fediverse software are not that interspersed, so it doesn't happen often, but it is a risk that has to be reflected in UI warnings, and one which gives a very uncomfortable feeling to users.

Why does it happen? OStatus did not have a concept of privacy when it was designed. The privacy features had to be added by me on top of the protocol. The problem is divided in two things:

  1. Status privacy is an extra attribute, rather than a core attribute, so when a parser doesn't know about the attribute, the default is public.

    Why this is so? I did not find a semantic way to encode messages differently. It is by all means all the same message, just private, so it didn't make sense to try to use a different ActivityStreams object-type or verb for it - especially considering that parsers might fallback to a default public text representation when encountering object-types or verbs they don't understand. The other possibility is wrapping the status XML inside some wrapper element. Perhaps even Base64-encoding it, like in the Salmon protocol ("magic-envelope"). I considered that base64 might give people a false sense of end-to-end encryption when it's really just a plaintext encoding. At the end of the day, I do not consider myself a web standard inventor, and the feeling in the community was such that people were willing to accept a best-effort mode for this feature rather than tight privacy (I did initially reject the idea of such a feature exactly because I knew it wouldn't be tight), so I went with the easy extra attribute

  2. The delivery mechanism for private toots is the same as for public toots - PubSubHubbub (now renamed to WebSub).

    I actually still stand behind this choice, because WebSub is the perfect mechanism for distributing content from a publisher to subscribers. It's as basic as it gets, and it would be silly to duplicate that functionality when it can be reused. However, exactly because it is so well-fitting, GNU social and other OStatus software would be equal subscribers to Mastodon instances, despite not handling private toots.

    Now, you must understand, we don't just let anyone subscribe to an Atom feed, and then push private toots to all subscribers, no. We filter subscribers such that a subscriber will only receive a toot if the author has a follower on that server. This means that if you lock your account (such as that you must approve followers before they're counted as followers), the distribution is tightly limited to servers your followers are from. The same is true with an unlocked account, but because anyone can follow you, it's sorta less tight. So far - seems good, how would you get your followers to see your content if you didn't trust their servers to send it to?

    The only problem is, that non-Mastodon software fits this pattern just as much. So it's an onus on the user to check whether their followers are on Mastodon or not... which despite UI warnings, people do not always understand, and it's pretty hard to do, and it feels insecure. (There is no protocol for self-identifying of software, or even "instances" themselves - protocol-wise an instance is but a byproduct of multiple users sharing the same domain name)

So to summarize, the problem is that private toots should've been a breaking-compatibility change, but weren't.

Solution: HTTP signatures (#4146, #4205) is a nice simple way of connecting an OStatus user (and by extension, "instance") to a HTTP request. This is meant for cross-server access-control. It's kind of no big deal, however, we can mandate that a PuSH subscription must be signed that way for private toots to be sent to it. It doesn't even matter which user is picked for the signature, we're only interested in the "domain" part of the user. It's not hard to implement, however it would take deliberate implementation on the part of other software. That way, it would become a compatibility barrier that affects only private toots.


What this doesn't solve:

  • Trusting your own sysadmin not to read private toots (nothing is private from sysadmins)
  • Trusting remote servers' sysadmins (same as above)

That can only be solved by end-to-end encryption, which by definition cannot be implemented on the server, so I am powerless (though I can simplify key exchange with some kind of API)

What this also doesn't solve:

  • There is another delivery mechanism - Salmon. That's used for delivering a status directly to its recipients (mentioned people). So solution to problem 2 doesn't affect it since it's entirely based on problem 1. So when you mention people, the status will always travel to those people, even if their servers don't support status privacy.
@Gargron

This comment has been minimized.

Copy link
Member Author

commented Jul 15, 2017

What this also doesn't solve:

There is another delivery mechanism - Salmon. That's used for delivering a status directly to its recipients (mentioned people). So solution to problem 2 doesn't affect it since it's entirely based on problem 1. So when you mention people, the status will always travel to those people, even if their servers don't support status privacy.

This and the main issue of this thread would also be solved by ActivityPub, which provides core syntax for message privacy. However, ActivityPub implementation is taking time.

@akihikodaki

This comment has been minimized.

Copy link
Collaborator

commented Jul 15, 2017

I'm for this proposal, but I note that encryption would be better to keep the capability of end-to-end security in the protocol.

OStatus allows each accounts to have its own key. That is meaningless for GNU Social and Mastodon, which requires users to trust servers. However, it allows to create another software, or extend those implementations, to ensure end-to-end integrity.

Private toots requires confidentiality as well. Though TLS would be sufficient for Mastodon, we should consider to allow to use encryption using keys of accounts and to have end-to-end confidentiality, especially if we respect the thought of OStatus.

@sydneyfalk

This comment has been minimized.

Copy link

commented Jul 15, 2017

I like akihikodaki's suggestion -- although I was unaware of the account key option. Good to know. ^_^

What I'd almost suggest is splitting 'private' into two types, effectively -- the toots we know (and sort of love) would eventually migrate to ActivityPub, and in the meantime will be "potentially going to servers" and such, all warnings in place, etc.

A toot status ABOVE that in security (or below it in terms of distribution nature, I suppose, depending on one's view of things), with its own different name (which I don't have a great suggestion for at the moment!) could exist, and either

  • that status could be encrypted with the Masto user's private key (kept only by the admin), which only followers could see the decrypted version of since followers of those users get the public keys on their keychain (if I'm understanding how that'd be implemented correctly, at least)

OR

  • messages of that status could be redesigned specifically to fail when trying to propagate to OStatus instances entirely through a specific, systematic malformation of the underlying structure

The former would require some infrastructural things that I haven't the foggiest about the feasibility/implementation-ease of, but I think it's possible. The latter would probably require much less, although I suppose the latter may seem a little gray-area in terms of ethics -- it's arguably sending information you KNOW is going to fail on the other end, and no doubt some will consider that intentional noise traffic in some senses -- but I think it'd kind of solve the problem without requiring addition of encryption for true E-to-E.

Either way, it'd leave 'private' messages for people who consider that sufficient privacy (and don't care if GNU/Social can see their messages, and so any of their GS followers can see them properly and such) and give something more approaching 'secure' for those of us who are doing everything to avoid GNU/Social.

(Also, this is a take from someone unfamiliar with the code, obviously -- but hopefully something in here's a useful idea, or a bread crumb leading to one. ^_^)

@akihikodaki

This comment has been minimized.

Copy link
Collaborator

commented Jul 16, 2017

  • that status could be encrypted with the Masto user's private key (kept only by the admin), which only followers could see the decrypted version of since followers of those users get the public keys on their keychain (if I'm understanding how that'd be implemented correctly, at least)

Actually public keys can be retrieved just by knocking WebFinger and that does not require to follow the account, so that does not work.
I also think private toots mentioned here is of the type called "direct toots": visible for mentioned accounts, but not for others, even if they are following the account.

To ensure privacy of such statuses, they should be encrypted with public keys of recipients. Recipients can decrypt them with their private keys.

Implementing such features would not be so difficult, but we should be careful since that would be a radical change in the protocol.

EDIT: the protocol would involve XML Encryption or a similar protocol.
https://www.w3.org/TR/xmlenc-core/

@sydneyfalk

This comment has been minimized.

Copy link

commented Jul 16, 2017

they should be encrypted with public keys of recipients

Well, there's a reason I don't work in development ^_^

that would be a radical change in the protocol

This is why I was suggesting a separate message type for them, one specific to Mastodon that wouldn't play with OStatus at all -- retaining the 'private' message type exists for people who are just looking to propagate to specific users (and their instances), and adding a 'locked' message type or something that's specifically only going to work with Mastodon instances.

My understanding was that the protocol can be added to by Masto in this way but required messaging still has to be allowed for things not being added on to for Masto-specific elements.

(Hopefully that clarifies -- and again, I realize the concept may be wrong, sorry if it's not helpful! ^_^ )

@multiple-creatures multiple-creatures referenced this issue Jul 22, 2017
1 of 1 task complete
@benediktg benediktg referenced this issue Aug 22, 2017
1 of 2 tasks complete
@Gargron

This comment has been minimized.

Copy link
Member Author

commented Sep 7, 2017

Closed because we picked switching to ActivityPub instead.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
3 participants
You can’t perform that action at this time.