internal/middleware: validate only top domain (#158)

This commit is contained in:
Bobby DeSimone 2019-06-03 08:45:38 -07:00 committed by GitHub
parent e982e72146
commit 8de453dae3
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 35 additions and 33 deletions

View file

@ -12,6 +12,7 @@ import (
"github.com/pomerium/pomerium/internal/cryptutil"
"github.com/pomerium/pomerium/internal/httputil"
"golang.org/x/net/publicsuffix"
)
// SetHeaders ensures that every response includes some basic security headers
@ -66,7 +67,7 @@ func ValidateRedirectURI(rootDomain *url.URL) func(next http.Handler) http.Handl
httputil.ErrorResponse(w, r, err.Error(), http.StatusBadRequest)
return
}
if !SameSubdomain(redirectURI, rootDomain) {
if !SameDomain(redirectURI, rootDomain) {
httputil.ErrorResponse(w, r, "Invalid redirect parameter", http.StatusBadRequest)
return
}
@ -75,22 +76,17 @@ func ValidateRedirectURI(rootDomain *url.URL) func(next http.Handler) http.Handl
}
}
// SameSubdomain checks to see if two URLs share the same root domain.
func SameSubdomain(u, j *url.URL) bool {
if u.Hostname() == "" || j.Hostname() == "" {
// SameDomain checks to see if two URLs share the top level domain (TLD Plus One).
func SameDomain(u, j *url.URL) bool {
a, err := publicsuffix.EffectiveTLDPlusOne(u.Hostname())
if err != nil {
return false
}
uParts := strings.Split(u.Hostname(), ".")
jParts := strings.Split(j.Hostname(), ".")
if len(uParts) != len(jParts) {
b, err := publicsuffix.EffectiveTLDPlusOne(j.Hostname())
if err != nil {
return false
}
for i := 1; i < len(uParts); i++ {
if uParts[i] != jParts[i] {
return false
}
}
return true
return a == b
}
// ValidateSignature ensures the request is valid and has been signed with