(Illustration by Gaich Muramatsu)
On Fri, May 06, 2016 at 08:38:49PM -0400, Jan Harkes wrote: > On Fri, May 06, 2016 at 08:59:15PM +0200, u-myfx_at_aetey.se wrote: > > Nevertheless, one example to the contrary: > > > > There is nothing preventing an update client to happily talk > > to a wrong update server instance if the ip is spoofed and "scm" > > data on some server hosts already are inconsistent > > (iow there is a possibility of error escalation or recovery prevention). > > In that case I can put your mind at easy very easily. > > - There is only one update server in a realm, so a client cannot > accidentally talk to the wrong server within the same realm. > - The update clients and update server use the 'update token' as a shared > secret to set up their connections. > So any accidential or malicious other update server that happens to take > over the same IP as the official update server will not possess the > shared secret to succesfully fool the update client. And if it does have > the right shared secret, a serverid isn't going to save anything here. I am not worried about a man-in-the-middle who redirects traffic to a server under his control, but about one who redirects traffic from one service instance to another one. In the example I am discussing a combination of several circumstances: - corrupted consistency between different server instances so that they do not agree on who is scm - a malicious party who can modify ip-numbers in packets in transit Then an update client can be fooled to connect to a wrong/stale update server which for any reason wrongly believes that it is scm. As a result updates will be picked from a wrong source and they can happen to be stale or corrupted, and the situation will be undetectable for this update client. A shared secret does not protect against this kind of influence. The scenario above is artificially constructed but this does not mean it is impossible. > > From my perspective this is not any more of a layering violation than > > CN checking in TLS. > > TLS actually checks the common name in TLS, your server ids are some > opaque blob passed up the application and are not checked by RPC2. So > they can just as easily be implemented by adding a single RPC call right > after connection setup doing something like a 'GetServerId', and then > taking action in the client based on the result. This looks like a clean and hardly disputable approach, applying the check in the layer just above the rpc2 connection. Indeed such a check is not automatically useful/necessary for every protocol and thus rpc2 code might not be the most natural place for it. ( If there are multiple protocols making use of such a check, it probably should be "CheckServerId" (instead of Get...), to avoid to agree on a certain form and size of "serverid" and also to avoid the need to pass it over the wire - it can be long. A hash comparison with a generous hash size would do. The only downside I see is that this implies an additional rtt time at connection establishement, when the protocol applies the check. OTOH connection establishement is a heavy operation by itself and does not happen too often. If the check is done as an RPC, the extra rtt for the protocols which need this would be hardly noticeable. ) Such an RPC would have a tiny impact on the code size, would not postulate any modification of the existing code but allow for checking. What can be better! I agree otherwise that there is for the moment no practical impact of _not_ doing such a check. But when we make changes this can be useful for avoiding the need of related exhaustive analysis of every case. > This is actually quite close to what Coda clients do when they connect > to Coda servers, they send an RPC request to 'bind' the connection to a > specific volume, if the server claims it does not have the volume the > connection is closed. Given that this is a replica id (which of course can not be present on another server), we are certainly in the clear. > > > > Do you feel this would be expensive or risky? What would be the downsides, > > > > besides the corresponding API extension (adding a "server instance id" > Ok here is a simple answer. The server-id would probably end up as part > of the INIT2 packet, which then turns any Coda server into a source for > an amplification attack. Someone can send INIT1 packets from a fake > origin, which then result in some very large INIT2 sent to the victim. This would be bad indeed, but a change of the on-wire formats would be probably not necessary. > If you move it to the INIT4, by then the connection is already set up > and it can just as well get sent as the first RPC on the new connection. What I had in mind was mixing the data into the secret. This would not change the size of any packet but ensure that the secret verification fails as soon as there is a mismatch between what the client and the server supply as the "id". Supplying an empty "id" would be even fully compatible with peers running the current "instance-unaware" code. The strengthening step would look to me like a suitable place for mixing in the extra data. This would generalize rpc2 to naturally support services with multiple instances who share the authentication secret, despite being distinct, from the upper layer protocol's viewpoint. Coda servers are an example of such setup (they serve data which differs between the servers, but share the authentication secret). There are probably examples outside of Coda, too. Given that Coda is the only known rpc2 user and that we do not see apparent related vulnerabilities in its protocols, such a change is of course less relevant. Thanks Jan! RuneReceived on 2016-05-07 11:36:54