authenticate: validate signature on /.pomerium, /.pomerium/sign_in and /.pomerium/sign_out (#2048)

Co-authored-by: Caleb Doxsey <cdoxsey@pomerium.com>
This commit is contained in:
Travis Groth 2021-04-01 10:04:16 -04:00 committed by GitHub
parent c96ff595e5
commit 0635c838c9
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 117 additions and 18 deletions

View file

@ -597,12 +597,36 @@ func TestAuthenticate_userInfo(t *testing.T) {
pbNow, _ := ptypes.TimestampProto(now)
tests := []struct {
name string
url *url.URL
method string
sessionStore sessions.SessionStore
wantCode int
wantBody string
}{
{"good", http.MethodGet, &mstore.Store{Encrypted: true, Session: &sessions.State{ID: "SESSION_ID", IssuedAt: jwt.NewNumericDate(now)}}, http.StatusOK, ""},
{
"good",
mustParseURL("/"),
http.MethodGet,
&mstore.Store{Encrypted: true, Session: &sessions.State{ID: "SESSION_ID", IssuedAt: jwt.NewNumericDate(now)}},
http.StatusOK,
"",
},
{
"missing signature",
mustParseURL("/?pomerium_redirect_uri=http://example.com"),
http.MethodGet,
&mstore.Store{Encrypted: true, Session: &sessions.State{ID: "SESSION_ID", IssuedAt: jwt.NewNumericDate(now)}},
http.StatusBadRequest,
"",
},
{
"bad signature",
urlutil.NewSignedURL("BAD KEY", mustParseURL("/?pomerium_redirect_uri=http://example.com")).Sign(),
http.MethodGet,
&mstore.Store{Encrypted: true, Session: &sessions.State{ID: "SESSION_ID", IssuedAt: jwt.NewNumericDate(now)}},
http.StatusBadRequest,
"",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
@ -613,8 +637,13 @@ func TestAuthenticate_userInfo(t *testing.T) {
if err != nil {
t.Fatal(err)
}
o := config.NewAtomicOptions()
o.Store(&config.Options{
AuthenticateURLString: "https://authenticate.localhost.pomerium.io",
SharedKey: "SHARED KEY",
})
a := &Authenticate{
options: config.NewAtomicOptions(),
options: o,
state: newAtomicAuthenticateState(&authenticateState{
sessionStore: tt.sessionStore,
encryptedEncoder: signer,
@ -644,8 +673,7 @@ func TestAuthenticate_userInfo(t *testing.T) {
}),
templates: template.Must(frontend.NewTemplates()),
}
u, _ := url.Parse("/")
r := httptest.NewRequest(tt.method, u.String(), nil)
r := httptest.NewRequest(tt.method, tt.url.String(), nil)
state, err := tt.sessionStore.LoadSession(r)
if err != nil {
t.Fatal(err)
@ -656,7 +684,7 @@ func TestAuthenticate_userInfo(t *testing.T) {
r.Header.Set("Accept", "application/json")
w := httptest.NewRecorder()
httputil.HandlerFunc(a.userInfo).ServeHTTP(w, r)
a.requireValidSignatureOnRedirect(a.userInfo).ServeHTTP(w, r)
if status := w.Code; status != tt.wantCode {
t.Errorf("handler returned wrong status code: got %v want %v", status, tt.wantCode)
}
@ -779,3 +807,11 @@ func TestAuthenticate_SignOut_CSRF(t *testing.T) {
})
}
}
func mustParseURL(rawurl string) *url.URL {
u, err := url.Parse(rawurl)
if err != nil {
panic(err)
}
return u
}