From 584c715419e55f059aa54e7f897b1228094e0162 Mon Sep 17 00:00:00 2001 From: ozpool Date: Thu, 14 May 2026 11:31:49 +0530 Subject: [PATCH] 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 --- node/rpcstack.go | 4 +++- node/rpcstack_test.go | 7 +++++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/node/rpcstack.go b/node/rpcstack.go index 20d488b734..a7ceecaa7f 100644 --- a/node/rpcstack.go +++ b/node/rpcstack.go @@ -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 } diff --git a/node/rpcstack_test.go b/node/rpcstack_test.go index bd75dac4eb..0d09af84eb 100644 --- a/node/rpcstack_test.go +++ b/node/rpcstack_test.go @@ -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 {