outposts/proxy: correctly handle ?rd= param
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org> #1997
This commit is contained in:
		| @ -3,14 +3,45 @@ package application | |||||||
| import ( | import ( | ||||||
| 	"encoding/base64" | 	"encoding/base64" | ||||||
| 	"net/http" | 	"net/http" | ||||||
|  | 	"net/url" | ||||||
|  | 	"strings" | ||||||
| 	"time" | 	"time" | ||||||
|  |  | ||||||
| 	"github.com/gorilla/securecookie" | 	"github.com/gorilla/securecookie" | ||||||
|  | 	"goauthentik.io/api" | ||||||
| 	"goauthentik.io/internal/outpost/proxyv2/constants" | 	"goauthentik.io/internal/outpost/proxyv2/constants" | ||||||
| ) | ) | ||||||
|  |  | ||||||
|  | const ( | ||||||
|  | 	redirectParam = "rd" | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | func (a *Application) checkRedirectParam(r *http.Request) (string, bool) { | ||||||
|  | 	rd := r.Header.Get(redirectParam) | ||||||
|  | 	if rd == "" { | ||||||
|  | 		return "", false | ||||||
|  | 	} | ||||||
|  | 	u, err := url.Parse(rd) | ||||||
|  | 	if err != nil { | ||||||
|  | 		a.log.WithError(err).Warning("Failed to parse redirect URL") | ||||||
|  | 		return "", false | ||||||
|  | 	} | ||||||
|  | 	// Check to make sure we only redirect to allowed places | ||||||
|  | 	if a.Mode() == api.PROXYMODE_PROXY || a.Mode() == api.PROXYMODE_FORWARD_SINGLE { | ||||||
|  | 		if !strings.Contains(u.String(), a.ProxyConfig().ExternalHost) { | ||||||
|  | 			a.log.Warning("redirect URI did not contain external host") | ||||||
|  | 			return "", false | ||||||
|  | 		} | ||||||
|  | 	} else { | ||||||
|  | 		if !strings.HasSuffix(rd, *a.ProxyConfig().CookieDomain) { | ||||||
|  | 			return "", false | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	return u.String(), false | ||||||
|  | } | ||||||
|  |  | ||||||
| func (a *Application) handleRedirect(rw http.ResponseWriter, r *http.Request) { | func (a *Application) handleRedirect(rw http.ResponseWriter, r *http.Request) { | ||||||
| 	newState := base64.RawStdEncoding.EncodeToString(securecookie.GenerateRandomKey(32)) | 	newState := base64.RawURLEncoding.EncodeToString(securecookie.GenerateRandomKey(32)) | ||||||
| 	s, err := a.sessions.Get(r, constants.SeesionName) | 	s, err := a.sessions.Get(r, constants.SeesionName) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		s.Values[constants.SessionOAuthState] = []string{} | 		s.Values[constants.SessionOAuthState] = []string{} | ||||||
| @ -20,6 +51,11 @@ func (a *Application) handleRedirect(rw http.ResponseWriter, r *http.Request) { | |||||||
| 		s.Values[constants.SessionOAuthState] = []string{} | 		s.Values[constants.SessionOAuthState] = []string{} | ||||||
| 		state = []string{} | 		state = []string{} | ||||||
| 	} | 	} | ||||||
|  | 	rd, ok := a.checkRedirectParam(r) | ||||||
|  | 	if ok { | ||||||
|  | 		s.Values[constants.SessionRedirect] = rd | ||||||
|  | 		a.log.WithField("rd", rd).Trace("Setting redirect") | ||||||
|  | 	} | ||||||
| 	s.Values[constants.SessionOAuthState] = append(state, newState) | 	s.Values[constants.SessionOAuthState] = append(state, newState) | ||||||
| 	err = s.Save(r, rw) | 	err = s.Save(r, rw) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
|  | |||||||
		Reference in New Issue
	
	Block a user
	 Jens Langhammer
					Jens Langhammer