TUN-7628: Correct Host parsing for Access

Will no longer provide full hostname with path from provided
`--hostname` flag for cloudflared access to the Host header field.
This addresses certain issues caught from a security fix in go
1.19.11 and 1.20.6 in the net/http URL parsing.
This commit is contained in:
Devin Carr
2023-07-25 09:33:11 -07:00
parent bfeaa3418d
commit 81fe0bd12b
85 changed files with 22873 additions and 4442 deletions

View File

@@ -168,68 +168,6 @@ func validateIP(scheme, host, port string) (string, error) {
return fmt.Sprintf("%s://%s", scheme, host), nil
}
// originURL shouldn't be a pointer, because this function might change the scheme
func ValidateHTTPService(originURL string, hostname string, transport http.RoundTripper) error {
parsedURL, err := url.Parse(originURL)
if err != nil {
return err
}
client := &http.Client{
Transport: transport,
CheckRedirect: func(req *http.Request, via []*http.Request) error {
return http.ErrUseLastResponse
},
Timeout: validationTimeout,
}
initialRequest, err := http.NewRequest("GET", parsedURL.String(), nil)
if err != nil {
return err
}
initialRequest.Host = hostname
resp, initialErr := client.Do(initialRequest)
if initialErr == nil {
resp.Body.Close()
return nil
}
// Attempt the same endpoint via the other protocol (http/https); maybe we have better luck?
oldScheme := parsedURL.Scheme
parsedURL.Scheme = toggleProtocol(oldScheme)
secondRequest, err := http.NewRequest("GET", parsedURL.String(), nil)
if err != nil {
return err
}
secondRequest.Host = hostname
resp, secondErr := client.Do(secondRequest)
if secondErr == nil { // Worked this time--advise the user to switch protocols
_ = resp.Body.Close()
return errors.Errorf(
"%s doesn't seem to work over %s, but does seem to work over %s. Reason: %v. Consider changing the origin URL to %v",
parsedURL.Host,
oldScheme,
parsedURL.Scheme,
initialErr,
originURL,
)
}
return initialErr
}
func toggleProtocol(httpProtocol string) string {
switch httpProtocol {
case "http":
return "https"
case "https":
return "http"
default:
return httpProtocol
}
}
// Access checks if a JWT from Cloudflare Access is valid.
type Access struct {
verifier *oidc.IDTokenVerifier