The API endpoint security Problem

So I was going over this with Michal today and it’s very interesting, how do we handle the task of securing the exit and peer to peer endpoints? Do we even need to?

As a quick introduction we have a series of http endpoints that we use for most communication, in fact we use it for everything that’s not Babel or our initial peer discovery which by definition needs UDP to be multicast. For the peer to peer uses of these sockets (hello message essentially and later payment messages) security is questionably needed at all.

For the hellos we can generally assume that if your on a broadcast domain you can’t reliably MITM (since it would just hear both messages) and even then being the man in the middle of two peers doesn’t provide any advantage to just forwarding the traffic yourself. The worst case scenario here is some sort of payment MITM, but payments should go over the encrypted per hop tunnel. I’m not even sure how payment MITM would be profitable except as maybe a trust rating think.

The question occurs to me that we may want to secure all of our api calls as a matter of principle, simply because ‘it should go over a tunnel’ is something that you usually end up screwing up. There’s no reason to turn a traffic data leak into a payment highjacking vulnerability if we don’t have to.

The real and immediate issue here is the exits. We pre-exchange an exit’s Wireguard key and it’s Eth key, but ideally we would reduce the amount of configuration for the exit to just it’s mesh-ip or even some sort of domain name that we could resolve to a mesh ip. There’s also the matter of signup info (currently email) and internal exit ip that get sent back over cleartext http. It’s not good practice even in our isolated testing meshnets.

The options available to us are

  • Sign everything ourselves with eth key or wireguard key
  • self signed https where we figure out key exchange
  • ‘real’ https where we somehow have both the exit ip and a ‘real’ domain name to verify against

In all of these we have to deal with some sort of preexchanged info, the question is what and how easy it is to manage.

We should not be doing extra crypto that is already being done by the tunnels.

As for the exit nodes, what’s the problem that you are trying to solve?

The only problem I have been able to identify from your post is the fact that emails are sent back to the exit in plain text. While I agree that this is not ideal, it is perhaps one of our very least pressing problems.

So the only reason this isn’t a serious problem is because we pre-exchange wg and eth keys for exits.

@Jehan you could break the exit signup by providing an incorrect internal ip address in the message response, or messing with someone’s auth code on the way to the exit, of course you could just stop the message entierly. So I’m not sure that’s really worse.

From a peer to peer perspective I’m not really concerned as MITM is kinda a pointless concept when it’s just a dumb peer you forward traffic over so long as fraud prevention is considered.

By pre-exchange you mean the fact that we ship exit keys in the firmware, right?

AFAIK, there is not way to accomplish this without pre-exchanging keys, whether doing it ourselves, or depending on the ssl infrastructure.

We spent a few days a couple months ago going back and forth about this and we decided to ship our own keys. I don’t remember all the reasons, and I can’t find our written documentation of the decision any more.

I’m wondering what has changed.

As for the question of securing peer to peer endpoints in addition to the tunnel, the only thing this helps with is accidentally leaking out of the tunnel as a programming mistake. Increasing our program complexity does not seem like a good way to reduce programming mistakes.

If we are really worried about leaking out of the tunnel, then we should address this problem by some kind of check of whether or not the tunnel is active instead of clumsily repeating what the tunnel already does.

Hi Jehan,

I agree. Instead of just plain text HTTP requests for exit signup, we could in theory do a D-H first to arrive at a shared private key for a WireGuard tunnel. Not sure how well it will work with WireGuard but in theory would be possible. After being inside the tunnel we could probably add a HTTP header that would be a HMAC of the shared secret of wg key and a message as a proof, but if you’ll think about it, you’re already inside a secure tunnel, and additional signing wouldn’t change much.

On the other hand we could just put HTTPS on exit nodes to at least secure the HTTP requests. With self signed certs perhaps user would have to acknowledge this fact, but nothing should stop an exit node to have an issued certificate. The only thing we would ship with a router is a list of CAs which is public (i.e. https://github.com/bagder/ca-bundle/blob/master/ca-bundle.crt). Deploying (optional, configurable) HTTPS support would be probably simpliest way, and wouldn’t increase complexity/development time much. Thoughts?

I’m not great at cryptography, but I think the only way we can know that an exit is an exit that we want to trust is by knowing what its public key is. This is why we ship the public keys in the firmware.

We could use the ssl infrastructure to map domain name -> key, but the current technique seemed simpler

Definitely it makes sense. Is there some kind of API that would allow us to download new keys if we ever create new exit nodes?

@Jehan I talked this over with a friend at lunch, the only real issue is the email.

So we send the exit our own wireguard key, this could be mitm’d but if they do Wireguard’s key exchange will fail (since we already know the exits key and therefore we won’t accept a mitm key) this is the same as a malicious node just dropping the encrypted request.

The only problem here is that emails can be harvested and you can in theory infer somthing about how many clients the exit has based on the returned ip details.

If we really wanted to get serious about encrypting the email, we could just encrypt it to the pre shared exit node public key