W3C home > Mailing lists > Public > ietf-http-wg@w3.org > January to March 2014

Re: h2#373 HPACK attack mitigation options

From: Roberto Peon <grmocg@gmail.com>
Date: Wed, 5 Mar 2014 04:58:39 -0800
Message-ID: <CAP+FsNcPiFqwxyfQucJHhbpq_SH5qhB+UeK--9ahqnB=PUnk6Q@mail.gmail.com>
To: Eric Rescorla <ekr@rtfm.com>
Cc: Martin Thomson <martin.thomson@gmail.com>, HTTP Working Group <ietf-http-wg@w3.org>

On Wed, Mar 5, 2014 at 4:49 AM, Eric Rescorla <ekr@rtfm.com> wrote:

> On Wed, Mar 5, 2014 at 11:09 AM, Roberto Peon <grmocg@gmail.com> wrote:
>> On Wed, Mar 5, 2014 at 2:23 AM, Martin Thomson <martin.thomson@gmail.com>wrote:
>>> See https://github.com/http2/http2-spec/issues/373
>>> See also
>>> http://lists.w3.org/Archives/Public/ietf-http-wg/2014JanMar/0233.html
>>> So, we've been discussing ways forward with this, and I think that
>>> there is a general desire to proceed with HPACK, something we'll
>>> probably confirm today.  But that means that (in Adam's words) we'll
>>> have to "require[s] downstream technologies to maintain more
>>> invariants in order to avoid leaking sensitive information."
>>> I think that we can limit the exposure to this problem to a subset of
>>> HTTP implementations, rather than the full community of HTTP users.
>>> This would allow us to keep compression, which I think is an important
>>> part of the HTTP/2 feature set.  In particular, this would allow us to
>>> keep compression without significantly weakening it, as some people
>>> have suggested.
>>> Firstly, we will need to be super careful about properly identifying
>>> the subset of implementations that might be affected by this.  I do
>>> not want a situation where some implementers think that they can avoid
>>> implementing mitigations for this attack, when in fact they should be.
>>> An implementation is potentially affected by this attack if it allows
>>> multiple actors to influence the creation of HTTP header fields on the
>>> same connection.  It also requires that header fields provided by any
>>> one actor be kept secret from any other actor.  In the canonical
>>> example of a browser, the invariant we want to maintain is that any
>>> origin (the primary class of actor in that context) is unable to
>>> access header fields that are created by other origins, or the browser
>>> itself.
>>> I'll note that this is also potentially an issue for non-browsers that
>>> use proxies.
>>> In terms of mitigation, I have so far heard two options.  There may be
>>> others.  I don't think that we should pick one, but instead describe
>>> the principles underpinning both and what it would take to properly
>>> implement them.  Then allow implementations to decide what works best
>>> for them.
>>> Option 1 - Origin isolation
>>> This solution relies on identifying the actor that is producing each
>>> header field.  Each actor can only access entries in the table that
>>> they themselves have caused to be added.  Fields added by other actors
>>> cannot be seen and referenced.
>>> Browsers can use the web origin model [RFC6454] to identify actors.
>>> Much of the mechanisms needed are already used by browsers in other
>>> areas (image rendering, cross origin requests, script execution,
>>> etc...).
>>> The HTTP stack might mark certain header fields as "safe" and make
>>> these available to all origins.  For instance, in a browser, the
>>> entries for Accept or Accept-Encoding, which is usually fixed in
>>> browsers, and not really secret, so exporting those for reuse by other
>>> actors is a good idea.
>>> I believe that this solves the problem perfectly.  However...
>>> The first drawback is that this has worse utilization of the memory we
>>> allocate for header compression.
>>> When I mentioned this to Nick and Patrick, both basically recoiled in
>>> horror at the notion of having to implement this.  This option widens
>>> the interface to the HTTP stack and all the tracking adds complexity
>>> to what is already the trickiest piece of HTTP/2 to get right.  I can
>>> only imagine that this could be even harder for other implementations
>>> to get right, especially those that don't integrate their HTTP stack
>>> as closely as Firefox does.
>> This adds some complexity, but doesn't increase memory requirements, at
>> least not in non-attack cases.
>> Given the mechanism used for expiration of state in HPACK, this mechanism
>> results in a decrease in compressor efficiency mostly in the attack case,
>> which seems reasonable.
> Maybe I am misunderstanding. It seems like in the case where you
> have (a) sharding and (b) shared cookies across shards, doesn't
> this create a lot of replicas of those across the shards for each
> origin?
>> If no state is carried over from connection-to-connection, then causing
>> the connection to be torn down refereshes the counter's state, and it
>> becomes equivalent to limiting MAX_CONCURRENT_STREAMS.
>> A timer on this state that outlives the connection lifetime would work to
>> concretely define the number of bits/second which can be probed.
>> I'm confident that variant 1 with this would work.
>>  #2 is subtle and depends on more variables (how does the probability
>> compound, decrease, etc. Bleh.).
>>> My sense is that this is going to be basically ineffectual.  Since
>>> we're talking about a network attacker, I'm fairly certain that this
>>> attacker can cause a browser to instantiate new connections, simply by
>>> breaking an existing one.
>> Playing with this limits the number of attempts that can occur without
>> the server being informed of the evidence of the attack.
>> If there is a timer on reconnects, this ends up limiting the number of
>> bits/second which can be probed similarly to option 2 above.
>> There is a further option, which is "perfect" against this style of
>> attack, and is arguably simple. One can think of it as a variant of #1.
>> Option #4
>> Requests originating from a domain which is not the origin to which the
>> request is ultimately directed are disallowed to use *any* dynamic
>> compressor state.
> So this would be the same evaluation as with same origin policy but
> more strict? I.e., I have a connection to site A, and then site B
> pulls in a GIF from A vs. <img src>, but the second request doesn't
> get to use the compressor state?
> -Ekr
Received on Wednesday, 5 March 2014 12:59:07 UTC

This archive was generated by hypermail 2.4.0 : Friday, 17 January 2020 17:14:24 UTC