On 2023-06-19 18:27 +02, Omar Polo <[email protected]> wrote:
> currently httpd uses the name specified in the config `server' block
> which is not guaranteed to be a valid hostname.
>
> quoting rfc3875:
>
> The SERVER_NAME variable MUST be set to the name of the server host
> to which the client request is directed. It is a case-insensitive
> hostname or network address. It forms the host part of the
> Script-URI.
>
> [...]
>
> A deployed server can have more than one possible value for this
> variable, where several HTTP virtual hosts share the same IP
> address. In that case, the server would use the contents of the
> request's Host header field to select the correct virtual host.
>
> This is important since `block return' with $SERVER_NAME may be
> expanded to something invalid, or a fastcgi application that looks at
> SERVER_NAME (e.g. gotwebd or php) may receive stuff like
> "*.example.com" instead of a proper host name depending on the
> configuration.
>
> This introduces some redundancy with HTTP_HOST (which we have since
> all the HTTP headers become a fastcgi param in the form of HTTP_*).
>
> I'm relying on the fact that httpd disallows requests without a Host
> header, so that in the fastcgi path desc->http_host is not NULL.
>
> thoughts/ok?
I'm worried that we pass un-sanitized input through to fcgi.
Of course we are passing *a lot* of un-sanitized input through to fcgi,
so does this matter in the grand scheme of things?
But I'd like if server_http_parsehost() enforces syntactically valid
hostnames first.
There is valid_domain() in usr.bin/ssh/misc.c or res_hnok in
resolv.h. Which is probably fine to use since we don't care too much
about portable.
Ignoring those musings, diff is OK
>
>
> diff /usr/src
> commit - 0cb70ced01a203d011a17a85e0c08bbb95ac164d
> path + /usr/src
> blob - 073ab344079c6ee4ae422c6e7ad01c70a7002055
> file + usr.sbin/httpd/server_fcgi.c
> --- usr.sbin/httpd/server_fcgi.c
> +++ usr.sbin/httpd/server_fcgi.c
> @@ -333,7 +333,7 @@ server_fcgi(struct httpd *env, struct client *clt)
> goto fail;
> }
>
> - if (fcgi_add_param(¶m, "SERVER_NAME", srv_conf->name,
> + if (fcgi_add_param(¶m, "SERVER_NAME", desc->http_host,
> clt) == -1) {
> errstr = "failed to encode param";
> goto fail;
> blob - 08deda7d5f097683571264da0ff434553801f8f7
> file + usr.sbin/httpd/server_http.c
> --- usr.sbin/httpd/server_http.c
> +++ usr.sbin/httpd/server_http.c
> @@ -1245,9 +1245,10 @@ server_expand_http(struct client *clt, const char *val
> return (NULL);
> }
> if (strstr(val, "$SERVER_NAME") != NULL) {
> - if ((str = url_encode(srv_conf->name))
> - == NULL)
> + if (desc->http_host == NULL)
> return (NULL);
> + if ((str = url_encode(desc->http_host)) == NULL)
> + return (NULL);
> ret = expand_string(buf, len, "$SERVER_NAME", str);
> free(str);
> if (ret != 0)
>
--
In my defence, I have been left unsupervised.