node: match vhost allowlist case-insensitively

The vhost allowlist is normalised to lower-case in newVHostHandler, but
the Host header on incoming requests was compared without lower-casing
it first. This rejected mixed-case hostnames such as 'TeSt' or 'Test'
even when 'test' was present in --http.vhosts.

Lower-case the parsed host before the map lookup. Hostnames are
case-insensitive per RFC 3986 section 3.2.2.

Fixes #34692
This commit is contained in:
ozpool 2026-05-14 11:31:49 +05:30
parent da34eb59fd
commit 584c715419
2 changed files with 10 additions and 1 deletions

View file

@ -473,7 +473,9 @@ func (h *virtualHostHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
h.next.ServeHTTP(w, r)
return
}
if _, exist := h.vhosts[host]; exist {
// Hostnames are case-insensitive per RFC 3986 section 3.2.2, and the
// configured allowlist is normalized to lower-case in newVHostHandler.
if _, exist := h.vhosts[strings.ToLower(host)]; exist {
h.next.ServeHTTP(w, r)
return
}

View file

@ -62,6 +62,13 @@ func TestVhosts(t *testing.T) {
resp2 := rpcRequest(t, url, testMethod, "host", "bad")
assert.Equal(t, resp2.StatusCode, http.StatusForbidden)
// Hostnames are case-insensitive per RFC 3986; mixed-case Host headers
// must match a lower-cased allowlist entry. Regression for #34692.
for _, mixed := range []string{"TEST", "TeSt", "Test:1234"} {
resp := rpcRequest(t, url, testMethod, "host", mixed)
assert.Equal(t, http.StatusOK, resp.StatusCode, "host=%q should be accepted", mixed)
}
}
type originTest struct {