BUG/MEDIUM: h1: reject absolute http(s) URIs with an empty host
An absolute-form request target with the http or https scheme and an empty
host was accepted and forwarded verbatim to H1 servers, for instance:
GET http:///admin.internal/x HTTP/1.1\r\n\r\n
GET http://:8080/x HTTP/1.1\r\n\r\n
GET http://@/x HTTP/1.1\r\n\r\n
RFC9110#4.2.1 says that a recipient must reject such URIs as invalid. Here
the rules see an empty host (or ":8080") and the path "/admin.internal/x",
while servers relying on WHATWG-style URL parsers (e.g. NodeJS) take
"admin.internal" as the host and "/x" as the path. It's a parser
differential that may be used to bypass host or path based rules, depending
on the server.
Let's reject these requests, unless unsafe violations are accepted (then the
error is only captured). A reg-test was added for this.
Note that the "strange cases" C32 to C35 of the h1_host_normalization
reg-test explicitly verified that "GET http://:" with "host: :80" (or
"https://:" and "host: :443" / "host: :") were accepted and normalized to
"http:///" with an empty host. These cases are now rejected with a 400, so
the test was updated accordingly. Developers may want to double-check that
there was no other reason to accept them.
The validation of the request target was introduced by commit
25bcdb1d9
("BUG/MAJOR: h1: Be stricter on request target validation during message
parsing") in 3.0-dev12, which didn't cover this case. This should be
backported as far as 3.0.