- From: Cory Benfield <cory@lukasa.co.uk>
- Date: Tue, 28 Sep 2021 14:23:25 +0100
- To: Willy Tarreau <w@1wt.eu>
- Cc: Mark Nottingham <mnot@mnot.net>, HTTP Working Group <ietf-http-wg@w3.org>, Martin Thomson <mt@lowentropy.net>
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