diff --git a/internal/pkg/auth/user_login.go b/internal/pkg/auth/user_login.go index 822b7daff..3a46bb9a4 100644 --- a/internal/pkg/auth/user_login.go +++ b/internal/pkg/auth/user_login.go @@ -340,8 +340,12 @@ func cleanup(server *http.Server) { }() } -func openBrowser(pageUrl string) error { - var err error +func openBrowser(pageUrl string) (err error) { + err = utils.ValidateURLDomain(pageUrl) + if err != nil { + return err + } + switch runtime.GOOS { case "freebsd", "linux": // We need to use the windows way on WSL, otherwise we do not pass query diff --git a/internal/pkg/auth/utils.go b/internal/pkg/auth/utils.go index faf24b687..a1e7eaf77 100644 --- a/internal/pkg/auth/utils.go +++ b/internal/pkg/auth/utils.go @@ -98,12 +98,21 @@ func parseWellKnownConfiguration(httpClient apiClient, wellKnownConfigURL string if wellKnownConfig.Issuer == "" { return nil, fmt.Errorf("found no issuer") } + if utils.ValidateURLDomain(wellKnownConfig.Issuer) != nil { + return nil, fmt.Errorf("issuer is invalid") + } if wellKnownConfig.AuthorizationEndpoint == "" { return nil, fmt.Errorf("found no authorization endpoint") } + if utils.ValidateURLDomain(wellKnownConfig.AuthorizationEndpoint) != nil { + return nil, fmt.Errorf("authorization endpoint is invalid") + } if wellKnownConfig.TokenEndpoint == "" { return nil, fmt.Errorf("found no token endpoint") } + if utils.ValidateURLDomain(wellKnownConfig.TokenEndpoint) != nil { + return nil, fmt.Errorf("token endpoint is invalid") + } err = SetAuthField(IDP_TOKEN_ENDPOINT, wellKnownConfig.TokenEndpoint) if err != nil { diff --git a/internal/pkg/auth/utils_test.go b/internal/pkg/auth/utils_test.go index 6fd67fc75..228a2c94c 100644 --- a/internal/pkg/auth/utils_test.go +++ b/internal/pkg/auth/utils_test.go @@ -133,12 +133,12 @@ func TestParseWellKnownConfig(t *testing.T) { { name: "success", getFails: false, - getResponse: `{"issuer":"issuer","authorization_endpoint":"auth","token_endpoint":"token"}`, + getResponse: `{"issuer":"https://issuer.stackit.cloud/endpoint","authorization_endpoint":"https://auth.stackit.cloud/enpoint","token_endpoint":"https://token.stackit.cloud/endpoint"}`, isValid: true, expected: &wellKnownConfig{ - Issuer: "issuer", - AuthorizationEndpoint: "auth", - TokenEndpoint: "token", + Issuer: "https://issuer.stackit.cloud/endpoint", + AuthorizationEndpoint: "https://auth.stackit.cloud/enpoint", + TokenEndpoint: "https://token.stackit.cloud/endpoint", }, }, { @@ -158,21 +158,21 @@ func TestParseWellKnownConfig(t *testing.T) { { name: "missing_issuer", getFails: true, - getResponse: `{"authorization_endpoint":"auth","token_endpoint":"token"}`, + getResponse: `{"authorization_endpoint":"https://auth.stackit.cloud/enpoint","token_endpoint":"https://token.stackit.cloud/endpoint"}`, isValid: false, expected: nil, }, { name: "missing_authorization", getFails: true, - getResponse: `{"issuer":"issuer","token_endpoint":"token"}`, + getResponse: `{"issuer":"https://issuer.stackit.cloud/endpoint","token_endpoint":"https://token.stackit.cloud/endpoint"}`, isValid: false, expected: nil, }, { name: "missing_token", getFails: true, - getResponse: `{"issuer":"issuer","authorization_endpoint":"auth"}`, + getResponse: `{"issuer":"https://issuer.stackit.cloud/endpoint","authorization_endpoint":"https://auth.stackit.cloud/enpoint"}`, isValid: false, expected: nil, }, diff --git a/internal/pkg/utils/utils.go b/internal/pkg/utils/utils.go index 0cb50a3d4..594f411d3 100644 --- a/internal/pkg/utils/utils.go +++ b/internal/pkg/utils/utils.go @@ -4,6 +4,7 @@ import ( "encoding/base64" "fmt" "net/url" + "slices" "strings" "time" @@ -82,11 +83,19 @@ func ValidateURLDomain(value string) error { if err != nil { return fmt.Errorf("parse url: %w", err) } + urlHost := urlStruct.Hostname() if urlHost == "" { return fmt.Errorf("bad url") } + allowedSchemes := []string{ + "https", + } + if !slices.Contains(allowedSchemes, urlStruct.Scheme) { + return fmt.Errorf("unsupported protocol: %s", urlStruct.Scheme) + } + allowedUrlDomain := viper.GetString(config.AllowedUrlDomainKey) if !strings.HasSuffix(urlHost, allowedUrlDomain) { diff --git a/internal/pkg/utils/utils_test.go b/internal/pkg/utils/utils_test.go index 0b5a656af..03b270309 100644 --- a/internal/pkg/utils/utils_test.go +++ b/internal/pkg/utils/utils_test.go @@ -97,6 +97,21 @@ func TestValidateURLDomain(t *testing.T) { input: "", isValid: false, }, + { + name: "invalid protocol", + input: "http://example.stackit.cloud", + isValid: false, + }, + { + name: "no protocol", + input: "example.stackit.cloud", + isValid: false, + }, + { + name: "valid endpoint", + input: "https://service-account.api.stackit.cloud/token", + isValid: true, + }, } for _, tt := range tests {