Privacy issue: Private routes can deanonymize Safety Routes
There is an edge case in the handling of ping validation for nodes in the routing table:
Here's the desirable path for private route usage:
- Bob publishes a Private Route for others to connect to. The private route contains PeerInfo for the first hop of the route.
- Alice imports the Private Route and begins testing that route, connecting to it with a Safety Route.
- Alice communicates with Bob over the Combined Route
There is a sidechannel, however:
- Eve creates a node that never advertises itself, but has DialInfo and is reachable.
- Eve creates a single-use Private Route and publishes it
- Alice imports Eve's 'evil' Private Route and communicates with it with the normal desirable path
- Alice also adds the evil private route first hop as a node to its routing table
- All nodes in the routing table get regular direct pings as a liveness check
- Eve notices a direct node id pinging its 'evil' private route's first hop, and now knows the IP address of the owner safety route that connected to the private route.
- Eve now can correlate an identity to an IP address.
To eliminate this, we need to exclude PeerInfo that have only been discovered via private routes from being communicated with over anything without a safety route.
We can not and should not only ping nodes over safety routes, because there will -always- be a first hop to a safety route, and without proper housekeeping that first hop could be one of these 'evil' private route first hop nodes.
Resolution:
We should keep track of what privacy domains we have seen nodes in, and if a node has only been seen as part of a Private Route, it should be tested -only- via the private route test mechanism. We should also exclude these nodes from FindNodeQ results when asked for by other nodes, because that would also give away if a 'private route only' node has been seen by some victim node.
If we have seen a node as part of a normal 'FindNode' operation, then it is safe.
Effectively, we will add a flag to 'register_node_with_peer_info' that keeps track of the source of the peer info and excludes it from results if it was not added from a public find node operation or other non-private context.