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)) >=


Reply via email to