outposts/proxy: fix potential empty redirect, add tests
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org> #2141
This commit is contained in:
parent
47777529ac
commit
1c2b452406
9
.github/workflows/ci-outpost.yml
vendored
9
.github/workflows/ci-outpost.yml
vendored
|
@ -45,15 +45,6 @@ jobs:
|
|||
- name: Go unittests
|
||||
run: |
|
||||
go test -timeout 0 -v -race -coverprofile=coverage.out -covermode=atomic -cover ./... | go-junit-report > junit.xml
|
||||
- uses: testspace-com/setup-testspace@v1
|
||||
with:
|
||||
domain: ${{github.repository_owner}}
|
||||
- name: run testspace
|
||||
if: ${{ always() }}
|
||||
run: |
|
||||
gocov convert coverage.out | gocov-xml > coverage.xml
|
||||
testspace [outpost]junit.xml --link=codecov
|
||||
testspace [outpost]coverage.xml --link=codecov
|
||||
ci-outpost-mark:
|
||||
needs:
|
||||
- lint-golint
|
||||
|
|
|
@ -71,7 +71,7 @@ func TestForwardHandleNginx_Single_Claims(t *testing.T) {
|
|||
}
|
||||
|
||||
rr = httptest.NewRecorder()
|
||||
a.forwardHandleTraefik(rr, req)
|
||||
a.forwardHandleNginx(rr, req)
|
||||
|
||||
h := rr.Result().Header
|
||||
|
||||
|
|
|
@ -79,5 +79,6 @@ func (a *Application) proxyModifyRequest(u *url.URL) func(req *http.Request) {
|
|||
}
|
||||
|
||||
func (a *Application) proxyModifyResponse(res *http.Response) error {
|
||||
res.Header.Set("X-Powered-By", "authentik_proxy2")
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -26,21 +26,14 @@ func (a *Application) redirectToStart(rw http.ResponseWriter, r *http.Request) {
|
|||
if err == nil {
|
||||
a.log.WithError(err).Warning("failed to decode session")
|
||||
}
|
||||
redirectUrl := r.URL.String()
|
||||
// simple way to copy the URL
|
||||
u, _ := url.Parse(redirectUrl)
|
||||
// In proxy and forward_single mode we only have one URL that we route on
|
||||
// if we somehow got here without that URL, make sure we're at least redirected back to it
|
||||
if a.Mode() == api.PROXYMODE_PROXY || a.Mode() == api.PROXYMODE_FORWARD_SINGLE {
|
||||
u.Host = a.proxyConfig.ExternalHost
|
||||
}
|
||||
redirectUrl := urlJoin(a.proxyConfig.ExternalHost, r.URL.Path)
|
||||
if a.Mode() == api.PROXYMODE_FORWARD_DOMAIN {
|
||||
dom := strings.TrimPrefix(*a.proxyConfig.CookieDomain, ".")
|
||||
// In forward_domain we only check that the current URL's host
|
||||
// ends with the cookie domain (remove the leading period if set)
|
||||
if !strings.HasSuffix(r.URL.Hostname(), dom) {
|
||||
a.log.WithField("url", r.URL.String()).WithField("cd", dom).Warning("Invalid redirect found")
|
||||
redirectUrl = ""
|
||||
redirectUrl = a.proxyConfig.ExternalHost
|
||||
}
|
||||
}
|
||||
s.Values[constants.SessionRedirect] = redirectUrl
|
||||
|
|
81
internal/outpost/proxyv2/application/utils_test.go
Normal file
81
internal/outpost/proxyv2/application/utils_test.go
Normal file
|
@ -0,0 +1,81 @@
|
|||
package application
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"goauthentik.io/api"
|
||||
"goauthentik.io/internal/outpost/proxyv2/constants"
|
||||
)
|
||||
|
||||
func TestRedirectToStart_Proxy(t *testing.T) {
|
||||
a := newTestApplication()
|
||||
a.proxyConfig.Mode = api.PROXYMODE_PROXY.Ptr()
|
||||
a.proxyConfig.ExternalHost = "https://test.goauthentik.io"
|
||||
req, _ := http.NewRequest("GET", "/foo/bar/baz", nil)
|
||||
|
||||
rr := httptest.NewRecorder()
|
||||
a.redirectToStart(rr, req)
|
||||
|
||||
assert.Equal(t, http.StatusFound, rr.Code)
|
||||
loc, _ := rr.Result().Location()
|
||||
assert.Equal(t, "https://test.goauthentik.io/akprox/start", loc.String())
|
||||
|
||||
s, _ := a.sessions.Get(req, constants.SeesionName)
|
||||
assert.Equal(t, "https://test.goauthentik.io/foo/bar/baz", s.Values[constants.SessionRedirect])
|
||||
}
|
||||
|
||||
func TestRedirectToStart_Forward(t *testing.T) {
|
||||
a := newTestApplication()
|
||||
a.proxyConfig.Mode = api.PROXYMODE_FORWARD_SINGLE.Ptr()
|
||||
a.proxyConfig.ExternalHost = "https://test.goauthentik.io"
|
||||
req, _ := http.NewRequest("GET", "/foo/bar/baz", nil)
|
||||
|
||||
rr := httptest.NewRecorder()
|
||||
a.redirectToStart(rr, req)
|
||||
|
||||
assert.Equal(t, http.StatusFound, rr.Code)
|
||||
loc, _ := rr.Result().Location()
|
||||
assert.Equal(t, "https://test.goauthentik.io/akprox/start", loc.String())
|
||||
|
||||
s, _ := a.sessions.Get(req, constants.SeesionName)
|
||||
assert.Equal(t, "https://test.goauthentik.io/foo/bar/baz", s.Values[constants.SessionRedirect])
|
||||
}
|
||||
|
||||
func TestRedirectToStart_Forward_Domain_Invalid(t *testing.T) {
|
||||
a := newTestApplication()
|
||||
a.proxyConfig.CookieDomain = api.PtrString("foo")
|
||||
a.proxyConfig.Mode = api.PROXYMODE_FORWARD_DOMAIN.Ptr()
|
||||
a.proxyConfig.ExternalHost = "https://test.goauthentik.io"
|
||||
req, _ := http.NewRequest("GET", "/foo/bar/baz", nil)
|
||||
|
||||
rr := httptest.NewRecorder()
|
||||
a.redirectToStart(rr, req)
|
||||
|
||||
assert.Equal(t, http.StatusFound, rr.Code)
|
||||
loc, _ := rr.Result().Location()
|
||||
assert.Equal(t, "https://test.goauthentik.io/akprox/start", loc.String())
|
||||
|
||||
s, _ := a.sessions.Get(req, constants.SeesionName)
|
||||
assert.Equal(t, "https://test.goauthentik.io", s.Values[constants.SessionRedirect])
|
||||
}
|
||||
|
||||
func TestRedirectToStart_Forward_Domain(t *testing.T) {
|
||||
a := newTestApplication()
|
||||
a.proxyConfig.CookieDomain = api.PtrString("goauthentik.io")
|
||||
a.proxyConfig.Mode = api.PROXYMODE_FORWARD_DOMAIN.Ptr()
|
||||
a.proxyConfig.ExternalHost = "https://test.goauthentik.io"
|
||||
req, _ := http.NewRequest("GET", "/foo/bar/baz", nil)
|
||||
|
||||
rr := httptest.NewRecorder()
|
||||
a.redirectToStart(rr, req)
|
||||
|
||||
assert.Equal(t, http.StatusFound, rr.Code)
|
||||
loc, _ := rr.Result().Location()
|
||||
assert.Equal(t, "https://test.goauthentik.io/akprox/start", loc.String())
|
||||
|
||||
s, _ := a.sessions.Get(req, constants.SeesionName)
|
||||
assert.Equal(t, "https://test.goauthentik.io", s.Values[constants.SessionRedirect])
|
||||
}
|
Reference in a new issue