Properly parse HTTP host for verification

Also fix H2 transport to not verify if host is not defined
This commit is contained in:
yuhan6665 2024-07-06 17:12:49 -04:00
parent 4c51636788
commit b8c0768b16
5 changed files with 22 additions and 6 deletions

View file

@ -1,8 +1,6 @@
package http package http
import ( import (
"strings"
"github.com/xtls/xray-core/common" "github.com/xtls/xray-core/common"
"github.com/xtls/xray-core/common/dice" "github.com/xtls/xray-core/common/dice"
"github.com/xtls/xray-core/transport/internet" "github.com/xtls/xray-core/transport/internet"
@ -18,9 +16,12 @@ func (c *Config) getHosts() []string {
} }
func (c *Config) isValidHost(host string) bool { func (c *Config) isValidHost(host string) bool {
if len(c.Host) == 0 {
return true
}
hosts := c.getHosts() hosts := c.getHosts()
for _, h := range hosts { for _, h := range hosts {
if strings.Contains(strings.ToLower(host), strings.ToLower(h)) { if internet.IsValidHTTPHost(host, h) {
return true return true
} }
} }

View file

@ -39,7 +39,7 @@ func (s *server) Handle(conn net.Conn) (stat.Connection, error) {
if s.config != nil { if s.config != nil {
host := req.Host host := req.Host
if len(s.config.Host) > 0 && !strings.Contains(strings.ToLower(host), strings.ToLower(s.config.Host)) { if len(s.config.Host) > 0 && !internet.IsValidHTTPHost(host, s.config.Host) {
return nil, errors.New("bad host: ", host) return nil, errors.New("bad host: ", host)
} }
path := s.config.GetNormalizedPath() path := s.config.GetNormalizedPath()

View file

@ -1,3 +1,18 @@
package internet package internet
import (
"net"
"strings"
)
//go:generate go run github.com/xtls/xray-core/common/errors/errorgen //go:generate go run github.com/xtls/xray-core/common/errors/errorgen
func IsValidHTTPHost(request string, config string) bool {
r := strings.ToLower(request)
c := strings.ToLower(config)
if strings.Contains(r, ":") {
h, _, _ := net.SplitHostPort(r)
return h == c
}
return r == c
}

View file

@ -72,7 +72,7 @@ func (h *requestHandler) upsertSession(sessionId string) *httpSession {
} }
func (h *requestHandler) ServeHTTP(writer http.ResponseWriter, request *http.Request) { func (h *requestHandler) ServeHTTP(writer http.ResponseWriter, request *http.Request) {
if len(h.host) > 0 && !strings.Contains(strings.ToLower(request.Host), strings.ToLower(h.host)) { if len(h.host) > 0 && !internet.IsValidHTTPHost(request.Host, h.host) {
errors.LogInfo(context.Background(), "failed to validate host, request:", request.Host, ", config:", h.host) errors.LogInfo(context.Background(), "failed to validate host, request:", request.Host, ", config:", h.host)
writer.WriteHeader(http.StatusNotFound) writer.WriteHeader(http.StatusNotFound)
return return

View file

@ -38,7 +38,7 @@ var upgrader = &websocket.Upgrader{
} }
func (h *requestHandler) ServeHTTP(writer http.ResponseWriter, request *http.Request) { func (h *requestHandler) ServeHTTP(writer http.ResponseWriter, request *http.Request) {
if len(h.host) > 0 && !strings.Contains(strings.ToLower(request.Host), strings.ToLower(h.host)) { if len(h.host) > 0 && !internet.IsValidHTTPHost(request.Host, h.host) {
errors.LogInfo(context.Background(), "failed to validate host, request:", request.Host, ", config:", h.host) errors.LogInfo(context.Background(), "failed to validate host, request:", request.Host, ", config:", h.host)
writer.WriteHeader(http.StatusNotFound) writer.WriteHeader(http.StatusNotFound)
return return