diff --git a/plugins/host_websocket.go b/plugins/host_websocket.go index 90403f4c0..8bedf5dc7 100644 --- a/plugins/host_websocket.go +++ b/plugins/host_websocket.go @@ -5,6 +5,7 @@ import ( "errors" "fmt" "maps" + "net" "net/http" "net/url" "strings" @@ -245,8 +246,11 @@ func (s *webSocketServiceImpl) getConnection(connectionID string) (*wsConnection func (s *webSocketServiceImpl) isHostAllowed(host string) bool { // Strip port from host if present hostWithoutPort := host - if idx := strings.LastIndex(host, ":"); idx != -1 { - hostWithoutPort = host[:idx] + if h, _, err := net.SplitHostPort(host); err == nil { + hostWithoutPort = h + } else if h, ok := strings.CutPrefix(host, "["); ok { + // Bracketed IPv6 literal with no port + hostWithoutPort = strings.TrimSuffix(h, "]") } for _, pattern := range s.requiredHosts { diff --git a/plugins/host_websocket_test.go b/plugins/host_websocket_test.go index e41cfbb82..15028acd2 100644 --- a/plugins/host_websocket_test.go +++ b/plugins/host_websocket_test.go @@ -614,3 +614,18 @@ func findWebSocketService(m *Manager, pluginName string) *webSocketServiceImpl { } return nil } + +var _ = Describe("isHostAllowed", func() { + DescribeTable("strips the port before matching", + func(allowed []string, host string, expected bool) { + svc := &webSocketServiceImpl{requiredHosts: allowed} + Expect(svc.isHostAllowed(host)).To(Equal(expected)) + }, + Entry("hostname with port", []string{"example.com"}, "example.com:8080", true), + Entry("hostname without port", []string{"example.com"}, "example.com", true), + Entry("IPv4 with port", []string{"127.0.0.1"}, "127.0.0.1:4533", true), + Entry("IPv6 with port", []string{"::1"}, "[::1]:8080", true), + Entry("IPv6 without port", []string{"::1"}, "[::1]", true), + Entry("IPv6 not in the list", []string{"::2"}, "[::1]:8080", false), + ) +})