2023-03-28 22:48:58 +00:00
|
|
|
// Copyright (c) HashiCorp, Inc.
|
2023-08-11 13:12:13 +00:00
|
|
|
// SPDX-License-Identifier: BUSL-1.1
|
2023-03-28 22:48:58 +00:00
|
|
|
|
2020-05-12 01:59:29 +00:00
|
|
|
package oidcauth
|
|
|
|
|
|
|
|
import (
|
|
|
|
"net/url"
|
|
|
|
|
|
|
|
"github.com/hashicorp/consul/internal/go-sso/oidcauth/internal/strutil"
|
|
|
|
)
|
|
|
|
|
|
|
|
// validRedirect checks whether uri is in allowed using special handling for loopback uris.
|
|
|
|
// Ref: https://tools.ietf.org/html/rfc8252#section-7.3
|
|
|
|
func validRedirect(uri string, allowed []string) bool {
|
|
|
|
inputURI, err := url.Parse(uri)
|
|
|
|
if err != nil {
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
|
|
|
|
// if uri isn't a loopback, just string search the allowed list
|
|
|
|
if !strutil.StrListContains([]string{"localhost", "127.0.0.1", "::1"}, inputURI.Hostname()) {
|
|
|
|
return strutil.StrListContains(allowed, uri)
|
|
|
|
}
|
|
|
|
|
|
|
|
// otherwise, search for a match in a port-agnostic manner, per the OAuth RFC.
|
|
|
|
inputURI.Host = inputURI.Hostname()
|
|
|
|
|
|
|
|
for _, a := range allowed {
|
|
|
|
allowedURI, err := url.Parse(a)
|
|
|
|
if err != nil {
|
|
|
|
return false // shouldn't happen due to (*Config).Validate checks
|
|
|
|
}
|
|
|
|
allowedURI.Host = allowedURI.Hostname()
|
|
|
|
|
|
|
|
if inputURI.String() == allowedURI.String() {
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return false
|
|
|
|
}
|