Review of draft-thomson-http-replay-latest

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