Re: New Version Notification for draft-thomson-http-replay-00.txt

I think we've been at least partially talking past each other, and I can
take the blame for some of that -- you seem to have been trying to keep
a narrow focus on the question of whether the Early-Data header is sent
on the first hop, and I've been expounding on various other potential
issues in the 0-RTT ecosystem that are not really relevant to that more
narrow question.

On 07/27/2017 04:01 PM, Willy Tarreau wrote:
> On Thu, Jul 27, 2017 at 03:16:28PM -0500, Benjamin Kaduk wrote:
>> On 07/27/2017 02:50 PM, Willy Tarreau wrote:
>>> On Thu, Jul 27, 2017 at 01:45:34PM -0500, Benjamin Kaduk wrote:
>>>>>> I just want to point out that 4NN was not a *guarantee* that the request
>>>>>> will not be replayed
>>>>> Yes it is. The only way to get this 4NN is for the connection to have
>>>>> been maintained between the client and the server for the whole duration.
>>>>> An attacker duplicating the traffic cannot use it against a new connection
>>>>> because the ClientFinished depends on the handshake.
>>>> I think we may be using different vocabulary/definitions.
>>>>
>>>> Alice makes a TCP connection to Bob, starts up a TLS 1.3 handshake and
>>>> sends some early data with it containing an HTTP request.  Eve has a tap
>>>> in the network and records the bits going Alice-->Bob.  Bob sends a TLS
>>>> 1.3 ServerHello/EncryptedExtensions/Finished and a 4NN in its 0.5-RTT
>>>> data.  Nothing stops Eve from taking a copy of those recorded bits and
>>>> sending them towards Bob's clone Robert that shares a cert+key.  Are
>>>> there requirements on Robert's behavior when receiving those bits?  I
>>>> claim that with the -00, Robert is permitted to give 200 and an actual
>>>> response, but with pull/25, Robert is obliged to also return a 4NN.
>>> I don't see how this would make any difference. In before pull/25, both
>>> Alice and Eve send the request as early data without ClientFinished. This
>>> *without ClientFinished* is the signal that the request is at risk. After
>>> pull/25, both Alice and Eve send the request as early data without
>>> ClientFinished and both with the EarlyData header field. This one becomes
>>> the signal. In both cases, it requires both Bob and Robert to have the
>>> same configuration, so nothing was saved by adding EarlyData.
>> My claim is with regarding Bob/Robert's decision about whether a given
>> (early) request can safely be processed as early data (vs. needing to be
>> verified by waiting for ClientFinished or sending 4NN for 1-RTT retry)
>> -- that is, whether they must necessarily make the same decision for a
>> given request.  You mention that they must have the same configuration,
>> but but what if the current system load also is used in making the
>> decision?
> It doesn't change the fact that the additional presence of the EarlyData
> header field added by the client makes no distinction here, it's just
> redundant with the connection using 0-RTT.

Yes (as covered in the other subthread).

>> My reading of pull/24 is that "MUST consistently use the same
>> approach" also implies must make the same decision.  If you think that
>> the -00 draft as-is implies that Robert and Bob must make the same
>> decision, I'd be happy to have that be the case.
> Having both of them rely on EarlyData demands that same for of consistency
> unfortunately so it doesn't add anything against this.

Both would have to know the request came in early data, whether via the
header or a direct query to the TLS stack, yes.  But that was something
of a fundamental prior assumption and not the "interesting" part of my
hypothetical, which was intended to be covering the decisions Robert/Bob
made when inspecting the body of the request (in the context of knowing
it was in early data).  But it sounds like we're happy to require
consistency from multi-server pools in this regard so I don't need to
continue trying/failing to expound about it.

> I mean, don't get me wrong, I'm not saying at all that there are not corner
> cases that we have to try to improve, what I'm saying is that the proposal
> to have the client add Early-Data was proposed solely for the timeout case
> and provides zero benefit for the case where the early data are replayed
> without ClientFinished (thus without the client being aware), and that's

Agreed

> precisely the limit of using 0-RTT, so if the whether *one* of the servers
> considers the request safe or not (configuration issue or anything) is out
> of our control. The principle is to let the server decide what action to
> take with requests received as Early Data.
>

I'm not sure I understand what you mean by "precisely the limit of using
0-RTT".  If I can attempt to rephrase what you're saying here it would
be that "we need to make sure that the server knows a given request was
(partially) received as early data (at some point in the chain), and the
server gets to decide whether it's safe enough to reply to right away. 
We can cover the consistency of behavior across servers as well, but
that is a separate issue."

>>> The point that Subodh made was that Bob would hijack Alice->Bob's connection
>>> and would delay the ClientFinished message so that the finalized request
>>> doesn't reach Bob. Alice, being fed up with waiting would *spontaneously*
>>> try again and succeed. Then Eve would unblock the packet and have Bob play
>>> the initial request again. The fault here is not a lack of identification
>>> that the first request was transported over early data, it's a fault from
>>> Alice who retried without being invited to do so nor knowing the consequences
>>> of doing so. And if this attack would work for a selection of Alices, then it
>>> would also work over TLS 1.2 as well because no transport information was used
>>> at all.
>> My understanding was that Subodh's point involve delaying not just the
>> ClientFinished but also the early data preceding it, so that Bob did not
>> even know there was a request at all, let alone one that is not
>> finalized.
> Not exactly since the Early Data has to be sent before the ClientFinished,
> the point was to be able to present Bob with a request carrying a validated
> ClientFinished (ie: Bob was supposed to trust it).

The point was to be able to present Bob with such a request, yes.  But
we also require that Bob does not just go ahead and process the request
without the ClientFinished, since then he would not be treating it as
validated early data.
Thinking about it more (and without presuming a specific set of
requirements of the many we are considering), the necessary situation
could be obtained in at least two ways: (1) blocking both the early data
and the ClientFinished, or (2) only blocking the ClientFinished and
relying on Bob using the strategy of "wait for ClientFinished before
processing the request".  In my previous mail I was only considering (1)
to the exclusion of (2); sorry about that.

>> When the early data + ClientFinished were allowed through
>> together, Bob would see the request, check that the handshake is
>> finished, and assume it was a 1-RTT request, even though Alice had
>> already timed out and retried.
> Yep.
>
>> I do not dispute that Alice could prevent the behavior by waiting to
>> receive a 4NN before retrying, though I also do not expect (e.g.)
>> browsers to universally adopt such behavior.
> But the point of the draft precisely is to explain how to safely map
> HTTP on top of early data and to explain the risks :-) If we start to
> say "let's not do it safely because some will surely bypass the rule
> anyway", it becomes a bit difficult to provide something really useful :-)

Yes, let's avoid "let's not do it safely because some will surely bypass
the rule
anyway" :)

> That's why I'm really all for documenting the corner cases so that
> implementers know what *not* to do (ie: even if a browser retries on
> timeout, it must absolutely not do it with early data). And anyway as
> Subodh showed, a browser retrying on timeout would be at risk whatever
> the transport level in use.
>
>> I agree that a client receiving 4NN has a guarantee that its request was
>> not processed on this connection.  Does it also have a guarantee that
>> (replays of) its request were not processed on any other connection
>> [even though those other connections would subsequently have the TLS
>> handshake fail]?
> Absolutely not, but it does have a guarantee that this request was not
> presented with a ClientFinished. So by virtue of the server having the
> final choice whether a request is safe to process as early data or not,
> the second will fail. The remaining cases where such a request is

Saying "the second will fail" without qualifications makes me a little
nervous, as it depends on the server's behavior/the consistency across
servers.  But I think I see what you are getting at, and agree.

> nevertheless processed are caused by different configurations, but adding
> headers on the client will not address misconfigured servers anyway (and
> would in fact make things worse by increasing the complexity, resulting
> in additional wrong combinations statically speaking).
>

I agree that adding more headers on the client won't help with
misconfigured servers.

-Ben

Received on Friday, 28 July 2017 13:28:28 UTC