mozilla / send

Simple, private file sharing from the makers of Firefox
https://send.firefox.com
Mozilla Public License 2.0
13.23k stars 1.55k forks source link

Design server architecture #10

Closed dannycoates closed 7 years ago

dannycoates commented 7 years ago

So webrtc is known to have connection issues in the real world. We've decided we don't want those issues to be a factor in this experiment. A more traditional client-server model should be more reliable but has a different set of challenges for our use case.

I would like to be able to revisit a P2P architecture in the future if this experiment proves successful. I think there's several benefits to P2P for both the users and us if the tech is reliable enough. With that in mind I'd like to keep the UX and service architecture to be "P2P compatible".

Here's what I imagine that to be:

  1. Sender makes a request to the server that creates a link to share
  2. Sender opens a websocket or xhr long poll to the server to wait for the Receiver to connect
  3. Receiver visits the link triggering a handshake with the Sender
  4. Via websockets or xhr a secure handshake and crypto happens 👋
  5. Sender starts uploading the encrypted data
  6. Receiver starts downloading the data a. Meanwhile the server is not storing the data anywhere
  7. The transfer completes and session is closed

What I like about it:

Possible downsides:

Thoughts?

dannycoates commented 7 years ago

Maybe encrypting the data itself isn't even useful in this case? The clients are connected to the server with TLS and they must trust the server anyway (it sent them the javascript)

chuckharmston commented 7 years ago

Maybe encrypting the data itself isn't even useful in this case? The clients are connected to the server with TLS and they must trust the server anyway (it sent them the javascript)

Encrypting at rest does provide an additional layer of privacy; it ensures that both Mozilla and any potential intruders don't have access to files that we're storing on users' behalf.

ekr commented 7 years ago

It seems like there are multiple levels of security here:

  1. Store the data in the clear.
  2. Store the data encrypted under a key which is in the URL (and is client-generated). If this is sent over a non-Mozilla channel, then this provides an improved level of security because we are unable to decrypt any data at rest, though we could retrospectively collude with the messaging channel to decrypt the data.
  3. Do some sort of E2E key exchange (e.g., DH) to establish a new key which would preclude collusion with the messaging channel. This would require active attack by the JS.
  4. (Eventually) have the Javacript digitally signed rather than in Web content.
dannycoates commented 7 years ago

@chuckharmston @ekr makes sense. In my OP I'm suggesting we don't store the data on our servers at all, just "pipe" it from one connection to the other. If we do end up storing it I totally agree it should be encrypted. Does it make sense to encrypt the data even if we don't store it?

ekr commented 7 years ago

@dannycoates: I'm not quite sure I understand how you are planning to do flow control here. you could easily end up with a lot of data on the server if one client is slow. I think #2 is still worth doing.

ghost commented 7 years ago

If we're going to have a server in the middle it makes sense to store the file there, for the speed differences mentioned, but also because needing to leave the tab open is an awkward interaction (this is something we can test, maybe I'm overestimating how unexpected that would be).

I also like #2. It gets us reasonable security with a straight forward and reliable implementation.

dannycoates commented 7 years ago

I'd like to try something like OP at some point. I've done something very similar at a previous job and it worked surprisingly well, especially on mobile. For now we'll stick with straight upload / download endpoints and nothing fancy, encrypted end-to-end with AES.