Hey,
i love your patch. The current behavour always bothered me because it
caused servers to display "wrong" sites as defaults for all requests
missing the Host header. I really like your patch and it works fine for
me on my servers.
However, i am not an official dev, so i cannot give you an ok.
So this is just feedback!
Greetings
Leo
On 2020-08-09 12:07, Ross L Richardson wrote:
At present, if a request contains no "Host:" header [HTTP pre-1.1] or
if the supplied header does not match any of the servers configured
in httpd.conf, the request is directed to the first server. This
isn't documented, AFAICT.
For example, if httpd.conf has just one server
server "www.example.com"
then we currently get
$ printf "HEAD / HTTP/1.0\r\nHost: www.openbsd.org\r\n\r\n" \
| nc www.example.com www | sed 1q
HTTP/1.0 200 OK
This behaviour strikes me as wrong (or at least sub-optimal) in the
case of non-matching "Host:" headers. The simplistic patch below
changes things to return a 404 status if no matching server is found.
[If status code 400 (bad request) is preferred, "goto fail;"
could be used.]
Justification:
- This seems more correct, and is consistent with the "fail closed"
approach.
- There is a net gain in functionality, as use of glob/patterns
wildcards can easily re-establish the current behaviour. In
contrast, there's no way at present to disable the implicit
match-anything behaviour.
If this is adopted, it should be document in current.html
A followup patch could merge this if statement with the one above it.
Several other issues exist in "Host:" header handling.
Ross
--
Index: server_http.c
===================================================================
RCS file: /cvs/src/usr.sbin/httpd/server_http.c,v
retrieving revision 1.140
diff -u -p -r1.140 server_http.c
--- server_http.c 3 Aug 2020 10:59:53 -0000 1.140
+++ server_http.c 9 Aug 2020 04:37:08 -0000
@@ -1200,7 +1200,7 @@ server_response(struct httpd *httpd, str
struct server_config *srv_conf = &srv->srv_conf;
struct kv *kv, key, *host;
struct str_find sm;
- int portval = -1, ret;
+ int hostmatch = 0, portval = -1, ret;
char *hostval, *query;
const char *errstr = NULL;
@@ -1277,16 +1277,20 @@ server_response(struct httpd *httpd, str
/* Replace host configuration */
clt->clt_srv_conf = srv_conf;
srv_conf = NULL;
+ hostmatch = 1;
break;
}
}
}
- if (srv_conf != NULL) {
+ if (host == NULL) {
/* Use the actual server IP address */
if (server_http_host(&clt->clt_srv_ss, hostname,
sizeof(hostname)) == NULL)
goto fail;
+ } else if (!hostmatch) {
+ server_abort_http(clt, 404, "not found");
+ return (-1);
} else {
/* Host header was valid and found */
if (strlcpy(hostname, host->kv_value, sizeof(hostname)) >=