Skip to content

Commit

Permalink
Merge pull request mesosphere#29 from k3a/k3a-cookies
Browse files Browse the repository at this point in the history
[1st & important] Fix domains and encryption key setup of securecookies with claims
  • Loading branch information
jr0d authored May 8, 2020
2 parents 5d70c6f + 11dc396 commit 06a0eb7
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 2 deletions.
9 changes: 8 additions & 1 deletion cmd/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package main

import (
"net/http"
"time"

"github.com/gorilla/sessions"
"k8s.io/client-go/kubernetes"
Expand Down Expand Up @@ -40,8 +41,14 @@ func main() {
clientset = nil
}

// Prepare cookie session store (first key is for auth, the second one for encryption)
cookieStore := sessions.NewCookieStore(config.Secret, []byte(config.SessionKey))
cookieStore.Options.MaxAge = int(config.Lifetime / time.Second)
cookieStore.Options.HttpOnly = true
cookieStore.Options.Secure = !config.InsecureCookie

// Build server
server := internal.NewServer(sessions.NewCookieStore([]byte(config.SessionKey)), clientset)
server := internal.NewServer(cookieStore, clientset)

// Attach router to default server
http.HandleFunc("/", server.RootHandler)
Expand Down
9 changes: 9 additions & 0 deletions internal/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,8 @@ func (c *Config) Validate() {
// Check for show stopper errors
if len(c.SecretString) == 0 {
log.Fatal("\"secret\" option must be set.")
} else if len(c.SecretString) < 32 {
log.Infoln("for better security, \"secret\" should ideally be 32 bytes or longer")
}

if c.ProviderUri == "" || c.ClientId == "" || c.ClientSecret == "" {
Expand All @@ -227,6 +229,13 @@ func (c *Config) Validate() {
}
c.ServiceAccountToken = strings.TrimSuffix(string(t), "\n")
}

// RBAC
if c.EnableRBAC && len(c.SessionKey) != 16 && len(c.SessionKey) != 24 && len(c.SessionKey) != 32 {
// Gorilla sessions require encryption keys of specific length
// https://www.gorillatoolkit.org/pkg/sessions#NewCookieStore
log.Fatal("\"session-key\" must be 16, 24 or 32 bytes long to select AES-128, AES-192, or AES-256 modes")
}
}

func (c *Config) SetOidcProvider() {
Expand Down
11 changes: 10 additions & 1 deletion internal/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -308,13 +308,22 @@ func (s *Server) AuthCallbackHandler() http.HandlerFunc {
logger.Printf("creating group claims session with groups: %v", groups)
session, err := s.sessionStore.Get(r, config.GroupsSessionName)
if err != nil {
logger.Errorf("failed to get group claims session: %v", err)
// from the .Get() documentation:
// "It returns a new session and an error if the session exists but could not be decoded."
// So it's ok to ignore and use the newly-created secure session! No need to hard-fail here.
logger.Errorf("unable to decode existing session with group claims (creating a new one): %v", err)
}

if session == nil {
// should never happen
http.Error(w, "Bad Gateway", 502)
return
}

session.Values["groups"] = make([]string, len(groups))
copy(session.Values["groups"].([]string), groups)

session.Options.Domain = cookieDomain(r)
if err := session.Save(r, w); err != nil {
logger.Errorf("error saving session: %v", err)
http.Error(w, "Bad Gateway", 502)
Expand Down

0 comments on commit 06a0eb7

Please sign in to comment.