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

Privacy leak: wormhole service links transactions to user's PC and mobile IP address #212

Open
tromer opened this issue Jan 4, 2020 · 6 comments

Comments

@tromer
Copy link

tromer commented Jan 4, 2020

Following up on a discussion in the Zecwallet UX - Replace Zecwallet UI with a React-based one grant proposal:

The connection between the Browser and Mobile App is done over the wormhole protocol. This is already built, and is currently how the App connects to Zecwallet. The connection uses TLS and the data inside is further encrypted end-to-end (with libsodium's symmetric encryption), so the wormhole service can't see the data either (But can see metadata like the IP address).

(where the wormhole protocol implementation is here.)

I'm worried about the privacy implications of the metadata and traffic patterns, because the centralized wormhole server can see the message timing, size and IP address of all PC-to-mobile communication.

For example, I guess that it's very easy to identify "transaction send" events just by the message sizes, in both the current architecture (where the mobile app is a UI frontend) and in the envisioned "web app" architecture (where the mobile app is a key store). The actual transactions are readily observable (on the peer-to-peer network, and at the lightwalletd service), and linkable by the timing. Hence:

The operator of the "wormhole" service, or anyone monitoring it, gets to know the IP address of both the PC and mobile phone of every sender of every transaction that uses this system.

That's bad.

A couple of ideas for improvements:

  1. Establish a direct TCP connection between the PC and mobile, when possible. For example, consider how Magic Wormhole falls back to its Transit Relay only if necessary:

The file-transfer commands also use a “Transit Relay”, which is another simple server that glues together two inbound TCP connections and transfers data on each to the other. The wormhole send file mode shares the IP addresses of each client with the other (inside the encrypted message), and both clients first attempt to connect directly. If this fails, they fall back to using the transit relay.

  1. Use Tor or I2P for the PC-to-mobile link
@adityapk00
Copy link
Collaborator

  1. The companion app protocol already attempts a direct connection first. It falls back to the wormhole connection if a direct connection cannot be made (The fallback explicitly opt-in). Details

  2. The PC and mobile both pad messages exchanged in either direction, so all messages are exactly the same size. The wormhole server can't deduce sends (or any other type of message)

@tromer
Copy link
Author

tromer commented Jan 4, 2020

  1. Can you explain more precisely how the direct connection mode works? Is it attempted just when you're on the same subnet, or will it also work if at least one side accepts incoming connection (no NAT or firewall block, or better yet, using means to traverse these such as STUN)?

  2. Great news about the padding. How large is it (transactions may get large)? Where is it documented?

@leto
Copy link

leto commented Jan 5, 2020

@tromer Direct Connection mode will work if the IP address + port on the LAN is accessible, otherwise it will not. It's somewhat "dumb" and does not try to do anything fancy. By default, if your device and zecwallet are on a different LAN, it will fail. The wormhole service must be enabled by the user.

A better design to solve issues mentioned by @tromer would be to decentralize the wormhole service, and have many of them to choose from. This could be via round robin DNS and also randomly choosing a server on startup (similar to Electrum) and also giving the option to use a custom wormhole server. This breaks the invariant that any one wormhole server would have all or most of the traffic. We have looked into doing this in Hush but haven't gotten around to it: MyHush/SilentDragonWormhole#2

@leto
Copy link

leto commented Jan 5, 2020

@tromer I was also happy to hear about the padding (as I maintain a fork of zecwallet) and wanted to know for myself the answer to your padding question. The code is here:

https://github.com/ZcashFoundation/zecwallet/blob/master/src/websockets.cpp#L404

It rounds all message sizes up to the next multiple of 256 bytes. Since many messages are small, this works well for those, but I believe some messages which are very large, such as "send a zxtn to these 20 zaddrs" would create a very large message which leaks some metadata. It's possible that 256 efficiently uses bandwidth but is not optimal for metadata leakage.

@leto
Copy link

leto commented Jan 12, 2020

@tromer @adityapk00 I did a simple metadata leakage analysis on this padding issue and confirmed that it does leak metadata about message types. Specifically, the message size (even after padding) of a z_sendmany is unique, and can be told apart from a getBalance request/response and from the much smaller getInfo request/responses.

The core issue is that the message padding of 256 was a good idea, but the value of 256 is too small to effectively make message types indistinguishable. TLDR: The solution is to use padding of 16KB, implemented here in Hush SilentDragon:

MyHush@6f230c9

I observed at least 4 different message type sizes, even after padding, within a few minutes of operation. These 4 buckets uniquely or almost-uniquely identify message types. A padding of 512 would increase privacy but would still give metadata, since some message types are very small (under 512 bytes) while z_sendmany/getBalance responses are just over 11KB. Using any padding amount less than 12KB will still leak metadata. I chose to pad to 16KB to take into account future changes to messages and as a buffer since I did not calculate the absolute largest a message could be. If Zecwallet/SilentDragon supported sending to many zaddrs at once in the future, those messages could be larger than 16KB and then leak metadata. So the best padding will always depend on the codebase and the largest message sizes.

@leto
Copy link

leto commented Aug 23, 2020

@tromer @adityapk00 ignoring this bug for 1.5 years is a dis-service to the privacy of Zcash users, and indeed, is one of the many reasons why I cannot recommend anybody use ZEC mainnet, since simple-to-fix and important privacy issues go unfixed for egregiously long periods of time.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants