webauthn: require session when accessing /.pomerium/webauthn (#3814)

* webauthn: require session when accessing /.pomerium/webauthn

* remove dead code

* remove unusued PomeriumDomains field
This commit is contained in:
Caleb Doxsey 2022-12-16 10:59:21 -07:00 committed by GitHub
parent 44a5c1b2fb
commit c86ca6f76f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 67 additions and 78 deletions

View file

@ -4,7 +4,6 @@ package webauthn
import (
"bytes"
"context"
"encoding/base64"
"encoding/json"
"errors"
"fmt"
@ -16,12 +15,10 @@ import (
"google.golang.org/grpc/status"
"google.golang.org/protobuf/types/known/timestamppb"
"github.com/pomerium/pomerium/internal/encoding/jws"
"github.com/pomerium/pomerium/internal/httputil"
"github.com/pomerium/pomerium/internal/middleware"
"github.com/pomerium/pomerium/internal/sessions"
"github.com/pomerium/pomerium/internal/urlutil"
"github.com/pomerium/pomerium/pkg/cryptutil"
"github.com/pomerium/pomerium/pkg/grpc/databroker"
"github.com/pomerium/pomerium/pkg/grpc/device"
"github.com/pomerium/pomerium/pkg/grpc/session"
@ -49,7 +46,6 @@ type State struct {
AuthenticateURL *url.URL
InternalAuthenticateURL *url.URL
Client databroker.DataBrokerServiceClient
PomeriumDomains []string
RelyingParty *webauthn.RelyingParty
Session *session.Session
SessionState *sessions.State
@ -423,39 +419,7 @@ func (h *Handler) saveSessionAndRedirect(w http.ResponseWriter, r *http.Request,
return err
}
// if the redirect URL is for a URL we don't control, just do a plain redirect
if !isURLForPomerium(state.PomeriumDomains, rawRedirectURI) {
httputil.Redirect(w, r, rawRedirectURI, http.StatusFound)
return nil
}
// sign+encrypt the session JWT
encoder, err := jws.NewHS256Signer(state.SharedKey)
if err != nil {
return err
}
signedJWT, err := encoder.Marshal(state.SessionState)
if err != nil {
return err
}
cipher, err := cryptutil.NewAEADCipher(state.SharedKey)
if err != nil {
return err
}
encryptedJWT := cryptutil.Encrypt(cipher, signedJWT, nil)
encodedJWT := base64.URLEncoding.EncodeToString(encryptedJWT)
// redirect to the proxy callback URL with the session
callbackURL, err := urlutil.GetCallbackURLForRedirectURI(r, encodedJWT, rawRedirectURI)
if err != nil {
return err
}
signedCallbackURL := urlutil.NewSignedURL(state.SharedKey, callbackURL)
httputil.Redirect(w, r, signedCallbackURL.String(), http.StatusFound)
httputil.Redirect(w, r, rawRedirectURI, http.StatusFound)
return nil
}
@ -533,18 +497,3 @@ func getOrCreateDeviceEnrollment(
}
return deviceEnrollment, nil
}
func isURLForPomerium(pomeriumDomains []string, rawURI string) bool {
uri, err := urlutil.ParseAndValidateURL(rawURI)
if err != nil {
return false
}
for _, domain := range pomeriumDomains {
if urlutil.StripPort(domain) == urlutil.StripPort(uri.Host) {
return true
}
}
return false
}