marten-seemann / draft-seemann-quic-address-discovery

Other
2 stars 0 forks source link

Handling of repeated observed address frames #12

Closed huitema closed 3 months ago

huitema commented 3 months ago

The spec says that "OBSERVED_ADDRESS frames are ack-eliciting, and SHOULD be retransmitted if lost." In a multipath environment, this is a bit problematic, because there is generally no guarantee that the frame will be resent on the same path as the first transmission. Indeed, it often makes a lost of sense to resend the content of lost packets on a different path, in particular when the original path is broken.

There are two potential fixes:

  1. encode a path ID in the frame, as in "I have observed this address and port on path number 42". This would be in line with multipath management frames like PATH_ABANDON or MP_ACK.
  2. add a recommendation that "OBSERVED_ADDRESS frames MUST be sent on the same path over which the address was received."

The first option is the natural solution when the multipath extension is negotiated.

The second option can be implemented, but is a bit painful. If I had to do that, I would just tie the OBSERVED_ADDRESS frames to PATH_CHALLENGE frames, and repeat them when the PATH_CHALLENGE needs to be repeated.

marten-seemann commented 3 months ago

I'd prefer to not have a dependency on QUIC multipath. Sure, you could set this field to 0 when using pure RFC 9000 QUIC, but it would be nice if we didn't have to do that.

When we a request-response protocol, we had the concept of a Request ID (remnants of which you can still see in the OBSERVED_ADDR frame, see #13), which tied a response to a request. This meant that it didn't matter which path the response was sent on.

2. add a recommendation that "OBSERVED_ADDRESS frames MUST be sent on the same path over which the address was received."

I think this is what we should do. I'm not sure how painful it is to implement, but I imagine that any multipath implementation will need some logic to tie certain frames to a specific path anyway.

huitema commented 3 months ago

Having the server (or the responder) send an observed frame each time it observes a new address is nice -- address changes due to NAT or whatever and poof, you get a frame. But there are potential issues, and a request response may be preferable after all.

First, the address "changes" may be trigger by third parties: capture a packet, make sure it does not reach its destination, then send it from an arbitrary address. The reaction to NAT traversal is a little slower, but could be triggered by the CID rotation done by the peer. The request mode seems a bit less prone to outside interference.

marten-seemann commented 3 months ago

First, the address "changes" may be trigger by third parties: capture a packet, make sure it does not reach its destination, then send it from an arbitrary address.

I'm wondering if this could be used by an on-path attacker to trigger a Honeybadger-style DoS attack: Capture all packets, and send them from 2 different interfaces in an alternating way, thereby triggering the sending of lots of OBSERVED_ADDRESS frames.

On the other hand, this attack is already possible, as any change in path requires the peer to go through path validation.

huitema commented 3 months ago

I actually simulate an attack like that in the picoquic test suite, for testing the robustness of NAT traversal. There are no good defense, but the code should at a minimum dampen the attack. Maybe document that in security considerations?