Skip to content

Commit

Permalink
chore: improve cookie handling + cleanup
Browse files Browse the repository at this point in the history
  • Loading branch information
mistahj67 committed Oct 24, 2024
1 parent 27c481e commit d7838ea
Show file tree
Hide file tree
Showing 2 changed files with 13 additions and 12 deletions.
13 changes: 11 additions & 2 deletions cmd/api/src/api/auth.go
Original file line number Diff line number Diff line change
Expand Up @@ -301,7 +301,11 @@ func (s authenticator) ValidateRequestSignature(tokenID uuid.UUID, request *http
}
}

func SetSecureBrowserCookie(request *http.Request, response http.ResponseWriter, name, value string, expires time.Time) {
func DeleteBrowserCookie(request *http.Request, response http.ResponseWriter, name string) {
SetSecureBrowserCookie(request, response, name, "", time.Now().UTC(), false)
}

func SetSecureBrowserCookie(request *http.Request, response http.ResponseWriter, name, value string, expires time.Time, httpOnly bool) {
var (
hostURL = *ctx.FromRequest(request).Host
sameSiteValue = http.SameSiteDefaultMode
Expand All @@ -323,6 +327,7 @@ func SetSecureBrowserCookie(request *http.Request, response http.ResponseWriter,
Name: name,
Value: value,
Expires: expires,
HttpOnly: httpOnly,
Secure: hostURL.Scheme == "https",
SameSite: sameSiteValue,
Path: "/",
Expand Down Expand Up @@ -351,6 +356,10 @@ func (s authenticator) CreateSSOSession(request *http.Request, response http.Res
}
case model.OIDCProvider:
//todo connect to db provider table

// Delete pre-auth cookies regardless
DeleteBrowserCookie(request, response, AuthPKCECookieName)
DeleteBrowserCookie(request, response, AuthStateCookieName)
break
case model.AuthSecret:
WriteErrorResponse(request.Context(), BuildErrorResponse(http.StatusBadRequest, "invalid auth provider", request), response)
Expand All @@ -371,7 +380,7 @@ func (s authenticator) CreateSSOSession(request *http.Request, response http.Res
locationURL := URLJoinPath(hostURL, UserInterfacePath)

// Set the token cookie
SetSecureBrowserCookie(request, response, AuthTokenCookieName, sessionJWT, time.Now().UTC().Add(s.cfg.AuthSessionTTL()))
SetSecureBrowserCookie(request, response, AuthTokenCookieName, sessionJWT, time.Now().UTC().Add(s.cfg.AuthSessionTTL()), false)

// Redirect back to the UI landing page
response.Header().Add(headers.Location.String(), locationURL.String())
Expand Down
12 changes: 2 additions & 10 deletions cmd/api/src/api/v2/auth/oidc.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ import (

"github.com/coreos/go-oidc/v3/oidc"
"github.com/specterops/bloodhound/headers"
"github.com/specterops/bloodhound/log"
"github.com/specterops/bloodhound/src/api"
"github.com/specterops/bloodhound/src/config"
"github.com/specterops/bloodhound/src/ctx"
Expand Down Expand Up @@ -69,8 +68,6 @@ func (s ManagementResource) OIDCLoginHandler(response http.ResponseWriter, reque
} else if provider, err := oidc.NewProvider(request.Context(), oidcProvider.Issuer); err != nil {
api.WriteErrorResponse(request.Context(), api.BuildErrorResponse(http.StatusInternalServerError, err.Error(), request), response)
} else {
log.Debugf("provider generated endpoints %+v", provider.Endpoint())

conf := &oauth2.Config{
ClientID: oidcProvider.ClientID,
Endpoint: provider.Endpoint(),
Expand All @@ -80,17 +77,15 @@ func (s ManagementResource) OIDCLoginHandler(response http.ResponseWriter, reque
// use PKCE to protect against CSRF attacks
// https://www.ietf.org/archive/id/draft-ietf-oauth-security-topics-22.html#name-countermeasures-6
verifier := oauth2.GenerateVerifier()
log.Debugf("LOGIN HANDLER - pkce verifier %s\n", verifier)

// Store PKCE on web browser in secure cookie for retrieval in callback
api.SetSecureBrowserCookie(request, response, api.AuthPKCECookieName, verifier, time.Now().UTC().Add(time.Hour))
api.SetSecureBrowserCookie(request, response, api.AuthPKCECookieName, verifier, time.Now().UTC().Add(time.Minute*7), true)

// Store State on web browser in secure cookie for retrieval in callback
api.SetSecureBrowserCookie(request, response, api.AuthStateCookieName, state, time.Now().UTC().Add(time.Hour))
api.SetSecureBrowserCookie(request, response, api.AuthStateCookieName, state, time.Now().UTC().Add(time.Minute*7), true)

// Redirect user to consent page to ask for permission for the scopes specified above.
redirectURL := conf.AuthCodeURL(state, oauth2.AccessTypeOffline, oauth2.S256ChallengeOption(verifier))
log.Debugf("Visit the URL for the auth dialog: %v", redirectURL)

response.Header().Add(headers.Location.String(), redirectURL)
response.WriteHeader(http.StatusFound)
Expand Down Expand Up @@ -131,8 +126,6 @@ func (s ManagementResource) OIDCCallbackHandler(response http.ResponseWriter, re
} else if idToken, err := oidcVerifier.Verify(request.Context(), rawIDToken); err != nil {
api.WriteErrorResponse(request.Context(), api.BuildErrorResponse(http.StatusBadRequest, "invalid id token", request), response)
} else {
log.Debugf("GOT A TOKEN %+v\n", token)
log.Debugf("ID TOKEN %+v\n", rawIDToken)
// Extract custom claims
var claims struct {
Name string `json:"name"`
Expand All @@ -143,7 +136,6 @@ func (s ManagementResource) OIDCCallbackHandler(response http.ResponseWriter, re
if err := idToken.Claims(&claims); err != nil {
api.WriteErrorResponse(request.Context(), api.BuildErrorResponse(http.StatusInternalServerError, err.Error(), request), response)
} else {
log.Debugf("ID CLAIMS %+v\n", claims)
s.authenticator.CreateSSOSession(request, response, claims.Email, oidcProvider)
}
}
Expand Down

0 comments on commit d7838ea

Please sign in to comment.