diff --git a/server/oauth2.go b/server/oauth2.go index ec972beab1..cc81a8a52d 100644 --- a/server/oauth2.go +++ b/server/oauth2.go @@ -668,7 +668,8 @@ func validateRedirectURI(client storage.Client, redirectURI string) bool { return true } - // verify that the host is of form "http://localhost:(port)(path)" or "http://localhost(path)" + // verify that the host is of form "http://localhost:(port)(path)", "http://localhost(path)" or numeric form like + // "http://127.0.0.1:(port)(path)" u, err := url.Parse(redirectURI) if err != nil { return false @@ -676,11 +677,20 @@ func validateRedirectURI(client storage.Client, redirectURI string) bool { if u.Scheme != "http" { return false } - if u.Host == "localhost" { + return isHostLocal(u.Host) +} + +func isHostLocal(host string) bool { + if host == "localhost" || net.ParseIP(host).IsLoopback() { return true } - host, _, err := net.SplitHostPort(u.Host) - return err == nil && host == "localhost" + + host, _, err := net.SplitHostPort(host) + if err != nil { + return false + } + + return host == "localhost" || net.ParseIP(host).IsLoopback() } func validateConnectorID(connectors []storage.Connector, connectorID string) bool { diff --git a/server/oauth2_test.go b/server/oauth2_test.go index 5f5fc3b663..2b733df825 100644 --- a/server/oauth2_test.go +++ b/server/oauth2_test.go @@ -452,6 +452,27 @@ func TestValidRedirectURI(t *testing.T) { redirectURI: "http://localhost", wantValid: true, }, + { + client: storage.Client{ + Public: true, + }, + redirectURI: "http://127.0.0.1:8080/", + wantValid: true, + }, + { + client: storage.Client{ + Public: true, + }, + redirectURI: "http://127.0.0.1:991/bar", + wantValid: true, + }, + { + client: storage.Client{ + Public: true, + }, + redirectURI: "http://127.0.0.1", + wantValid: true, + }, // Both Public + RedirectURIs configured: Could e.g. be a PKCE-enabled web app. { client: storage.Client{