haskell-distributed / distributed-process

Cloud Haskell core libraries
http://haskell-distributed.github.io
713 stars 97 forks source link

[NTTCP-7] handleConnectionRequest should not blindly believe theirAddress #439

Open qnikst opened 9 years ago

qnikst commented 9 years ago

[Imported from JIRA. Reported by Alexander Kjeldaas @ak) as NTTCP-7 on 2014-07-19 23:28:20] From casually reading the code, I'm worried about believing the received EndPointAddress in handleConnectionRequest.

In an environment where not all processes have the same credentials, this opens up the ability to spoof other processes.

If node A connects to node B and presents itself as node C, then this is a spoofing attempt.

(Not fixing this severely restricts the use-cases for CH).

Rather, I think what should be done is by default to screen the incoming EndPointAddress against Network.Socket.getPeerName and reject anything that does not match.

Bonus points for having a callback that can act as a "firewall" in case the transport is going through a NAT (in which case accepting the EndPointAddress is essential in getting bi-directional connectivity).

dcoutts commented 7 years ago

This has become an issue for a use case we've got so I'll be making a PR.

Rather, I think what should be done is by default to screen the incoming EndPointAddress against Network.Socket.getPeerName and reject anything that does not match.

I arrived at that conclusion independently, so that's a good sign.

So the endpoint address the originating side sends becomes just a sanity check. We would still have to believe the local endpoint id but that should be ok.

Related to this, we're preparing a patch to handle the case where the listening address for a transport is not the same as the public IP that others will see. This can happen in some cloud environments where it is essential to bind to 0.0.0.0 and the public IP is only available via config.

Bonus points for having a callback that can act as a "firewall" in case the transport is going through a NAT (in which case accepting the EndPointAddress is essential in getting bi-directional connectivity).

Right, for NAT only the address reported by getPeerName will be useful, and will only be useful temporarily while the heavyweight connection is up. Also, in a NAT situation the endpoint address supplied by the outgoing side will not be correct. So when we know we may be connecting from behind a NAT then we need to be able to not supply an endpoint address. That is safe since we would only use it as a sanity check for cases where we expect the node to be addressable later.

avieth commented 7 years ago

haskell-distributed/network-transport-tcp#54