- From: Victor Vasiliev <vasilvv@google.com>
- Date: Thu, 3 Aug 2017 13:54:51 -0400
- To: ietf-http-wg@w3.org, draft-thomson-http-replay@ietf.org
- Message-ID: <CAAZdMadYZmq0r0XwibMAjGs17DL11-zXMWBTJzBZoo76MpNCqg@mail.gmail.com>
First of all, I would like to thank the authors for taking up the work of writing this draft; a well-defined application profile for use of 0-RTT in HTTP was for a long time something that everyone believed should exist but no one actually worked on, and it's nice to finally see it materialize. Now, let's go to the most contentious point first. ## What does "early" mean? The profile does not define whether a single request can span from early to non-early data, or whether, say, a single HTTP/2 frame can cross that boundary (for TLS 1.3 over TCP). In general, there are two world views possible here: * Being "early" is an inherent property of data transmitted over TLS, with some data being inherently marked as "early" by virtue of being transmitted using early data keys. * Being "early" is a temporal property of the data; the data is early until the server receives a liveness proof from the client. (this is so far without taking into account relays) Both of those viewpoints provide the same level of security guarantee, specifically, the server can determine whether the data received is a potential replay or not. I would personally like advocate for the second model, due to following: 1. This approach works well for QUIC case where the boundary between early and regular data may not be well-defined (for instance, early data packet can be retransmitted with normal key, leading to early and non-early data being interleaved). 2. This approach allows the server to buffer up the request until the ClientHello is received in order to process it; if you believe in the first approach, this does not make sense since the early data is always early, and your only option is to always reject the request. 3. This approach allows the intermediary to retry the request after receiving 4NN from backend and liveness proof from the client, saving some time (more below). 4. There is no changes to parsing wire format required, since the liveness information is communicated to the application layer through a separate channel (liveness check function). ## Intermediaries The proposed Early-Data header scheme is solid, and seems to me like the only reasonable approach to solve the problem of interaction between the intermediaries and 0-RTT. The semantics of the header is currently tied to the first approach, the one where being "early" is the property of the data itself. This could be easily avoided by shifting the definition to the one based on desired security semantics instead of a particular mechanism: the header should be defined as "indication that the intermediary believes the request could potentially be a 0-RTT replay". I would also rename it to something like Not-Replay-Safe. 4NN error code should specify that the server must not process the request if it actually receives, and in general should have same semantics as HTTP/2 REFUSED_STREAM (I expect the user agents to implement them at the same place). I believe that with semantics above it should be safe for intermediaries retry requests on 4NN. This potentially saves the time it takes to process the request, from two full round-trip times between the client and the server to one full round-trip time plus largest of {RTT between client and intermediary, RTT between intermediary and server}. This, of course, can be done only if the intermediary did not receive Early-Data header from upstream, which is why it's important for the clients to not send Early-Data header. ## Pull request 25 So far, this has been a review of latest editor's copy of the draft. There is also https://github.com/martinthomson/http-replay/pull/25 I believe that this pull request should not be adopted. There is no good justification for drastic change of the proposed application profile (neither in text nor on the mailing list), and the attacks suggested are retry attacks and not replay attacks. The reasoning behind the change is extremely dangerous, as it seems to imply that Early-Data header could protect the clients from retry attacks, which it cannot. Commenters on this list have already pointed out that the similar class of retry attacks works with TLS 1.2. ## Minor points "replays are under the control of an attacker, and are therefore malicious" -- I am not sure "malicious" is the right word here; retries can be also attacker-induced. The important distinction is that replays can be done in much greater quantity and without the client's knowledge. ## Summary This draft is a very solid starting point, and I support its adoption as-is (and oppose its adoption if #25 is merged). I am grateful to Martin, Mark and Willy for taking on this essential work. I encourage the authors to converge on a stable header format and error code sooner rather than later, since wide adoption of 0-RTT is likely to happen fairly soon.
Received on Thursday, 3 August 2017 17:55:15 UTC