Re: Publication has been requested for draft-ietf-httpbis-http2bis-05

On Tue, 28 Sept 2021 at 11:13, Willy Tarreau <w@1wt.eu> wrote:
>
> Hi Cory,
>
> On Tue, Sep 28, 2021 at 10:55:03AM +0100, Cory Benfield wrote:
> > > I'd have liked that we suggest to be extremely careful about checking
> > > dangerous characters in some pseudo headers, which can be abused when
> > > concatenated to reconstruct a URI, and for which there are no indications
> > > in Semantics since they do not really exist outside of H2. Something like
> > > this could have done the job:
> >
> > I don't think this is true: -semantics defines these as "Control Data"
> > (Section 6.2) and points most of these constructs to other sections.
> >
> > For example, method is referenced in Section 9 and given the ABNF
> > `token`, which is a stricter constraint than you ask for here. Section
> > 7.2 covers :authority and gives it the ABNF uri-host [ ":" port ],
> > which again is a stricter constraint. Finally, the http2bis definition
> > of :path header calls out that its value is absolute-path, optionally
> > followed by ? and query, unless it is *.
>
> I know, but there is one particular case that significantly increases
> this risk, which is when you're adding H2 to code already supporting H1
> where the controls are performed later by code that you already trust for
> doing the right thing with elements extracted from H1. Then you assemble
> everything and parse the result via your well-trusted request-line parser.
> But it's too late, the space in :method, the "://" in :scheme, the "/" or
> space in :authority, or the space in :path have already defined different
> delimiters.

I'm nervous about the idea of adding normative requirements that are
there to defend against an implementation choice. In general if you
transform a HTTP/2 message into a HTTP/1.1 message before you parse it
you need to be careful, because it is extremely hard to identically
reproduce a HTTP/2 message in a HTTP/1.1 wire format. In some cases
it's not possible: for example, HTTP/2 does not allow chunked encoding
but does allow bodies on requests without a content length header,
while HTTP/1.1 is the other way around.

> > I don't know that we gain much by further constraints unless trying to
> > offer intermediaries an off-ramp for less specific enforcement. On the
> > other hand, most intermediaries cannot be agnostic to control data, so
> > they likely have to police this themselves.
>
> Sure but these are really not natural to process on the output of HPACK,
> in part because some of them most of the time come from the static
> dictionary itself (:method and :scheme) where nobody expects to find
> a ":" in a scheme for example :-/
>
> I mean, it's really easy to get trapped, and the long list of examples
> below tends to confirm it:
>
>    https://portswigger.net/research/http2
>
> I'd have liked to at least add that to the security recommendations.

I think my security recommendation would be much stronger: do not
naively attempt to serialise a HTTP/1.1 message from a HTTP/2 message.
There exists no simple string-formatting transformation of a valid
HTTP/2 message into a valid HTTP/1.1 message. To perform this
transformation it is necessary to parse the HTTP/2 message into a
structured, semantic form, and then re-serialize that message into
HTTP/1.1.

I'm not strongly opposed to doing this because, well, we did provide
guidance for other fields. But this does seem like it's a good
indication of how difficult this kind of guidance is: we end up having
to provide endless detailed exceptions that ultimately boil down to
"you cannot printf HTTP/2 to HTTP/1".

Received on Tuesday, 28 September 2021 13:24:01 UTC