identity/oidc: loopback redirect dynamic port (#13871)
* Add check for OIDC provider to permit a non-exact redirect URI from OIDC client if it is the IPv4 or IPv6 loopback address. * Update changelog/13871.txt Co-authored-by: Austin Gebauer <34121980+austingebauer@users.noreply.github.com> * Update redirectURI check to match that for the OIDC auth method. Co-authored-by: Austin Gebauer <34121980+austingebauer@users.noreply.github.com>
This commit is contained in:
parent
f85945d3aa
commit
8d169d48d3
|
@ -0,0 +1,3 @@
|
||||||
|
```release-note:bug
|
||||||
|
identity/oidc: Adds support for port-agnostic validation of loopback IP redirect URIs.
|
||||||
|
```
|
|
@ -1513,7 +1513,8 @@ func (i *IdentityStore) pathOIDCAuthorize(ctx context.Context, req *logical.Requ
|
||||||
if redirectURI == "" {
|
if redirectURI == "" {
|
||||||
return authResponse("", state, ErrAuthInvalidRequest, "redirect_uri parameter is required")
|
return authResponse("", state, ErrAuthInvalidRequest, "redirect_uri parameter is required")
|
||||||
}
|
}
|
||||||
if !strutil.StrListContains(client.RedirectURIs, redirectURI) {
|
|
||||||
|
if !validRedirect(redirectURI, client.RedirectURIs) {
|
||||||
return authResponse("", state, ErrAuthInvalidRedirectURI, "redirect_uri is not allowed for the client")
|
return authResponse("", state, ErrAuthInvalidRedirectURI, "redirect_uri is not allowed for the client")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,38 @@
|
||||||
|
package vault
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/url"
|
||||||
|
|
||||||
|
"github.com/hashicorp/go-secure-stdlib/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
|
||||||
|
}
|
||||||
|
allowedURI.Host = allowedURI.Hostname()
|
||||||
|
|
||||||
|
if inputURI.String() == allowedURI.String() {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
Loading…
Reference in New Issue