Skip to content

Commit

Permalink
Add check for OIDC provider to permit a non-exact redirect URI from O…
Browse files Browse the repository at this point in the history
…IDC client if it is the IPv4 or IPv6 loopback address.
  • Loading branch information
paladin-devops committed Feb 2, 2022
1 parent 057c67f commit 4a66798
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 1 deletion.
3 changes: 3 additions & 0 deletions changelog/13871.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
```release-note:bug
oidc: Support dynamic port for loopback redirect URI
```
3 changes: 2 additions & 1 deletion vault/identity_store_oidc_provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -1513,7 +1513,8 @@ func (i *IdentityStore) pathOIDCAuthorize(ctx context.Context, req *logical.Requ
if redirectURI == "" {
return authResponse("", state, ErrAuthInvalidRequest, "redirect_uri parameter is required")
}
if !strutil.StrListContains(client.RedirectURIs, redirectURI) {

if !strutil.StrListContains(client.RedirectURIs, redirectURI) && !isValidRedirectURI(redirectURI, client.RedirectURIs) {
return authResponse("", state, ErrAuthInvalidRedirectURI, "redirect_uri is not allowed for the client")
}

Expand Down
49 changes: 49 additions & 0 deletions vault/identity_store_oidc_provider_util.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package vault

import (
"net/url"
"regexp"
"strings"
)

func isValidRedirectURI(uri string, validUris []string) bool {
requestedUri, err := url.Parse(uri)
if err != nil {
return false
}

for _, validUri := range validUris {
if strings.ToLower(validUri) == strings.ToLower(uri) || isLoopbackURI(requestedUri, validUri) {
return true
}
}

return false
}

func isLoopbackURI(requestUri *url.URL, validUri string) bool {
registeredUri, err := url.Parse(validUri)
if err != nil {
return false
}

// Verifies that the valid URL is HTTP and is the loopback address before
// proceeding, otherwise return false
if registeredUri.Scheme != "http" || !isLoopbackAddress(registeredUri.Host) {
return false
}

// Returns true if the path after the IP/port is the same
// Request URL and valid URL have already been validated as loopback
if requestUri.Scheme == "http" && isLoopbackAddress(requestUri.Host) && registeredUri.Path == requestUri.Path {
return true
}

return false
}

// Returns true if the address hostname is the IPv4 or IPv6 loopback address and ignores port
func isLoopbackAddress(address string) bool {
match, _ := regexp.MatchString("^(127.0.0.1|\\[::1\\])(:?)(\\d*)$", address)
return match
}

0 comments on commit 4a66798

Please sign in to comment.