Skip to content

Commit

Permalink
Refactor OIDC redirect state to have nonce validation. Closes #2138.
Browse files Browse the repository at this point in the history
  • Loading branch information
knadh committed Nov 10, 2024
1 parent b995cce commit abe09d6
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 5 deletions.
37 changes: 35 additions & 2 deletions cmd/auth.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package main

import (
"encoding/base64"
"encoding/json"
"errors"
"net/http"
"net/mail"
Expand Down Expand Up @@ -28,6 +30,11 @@ type loginTpl struct {
Error string
}

type oidcState struct {
Nonce string `json:"nonce"`
Next string `json:"next"`
}

var oidcProviders = map[string]bool{
"google.com": true,
"microsoftonline.com": true,
Expand Down Expand Up @@ -107,7 +114,18 @@ func handleOIDCLogin(c echo.Context) error {
next = uriAdmin
}

return c.Redirect(http.StatusFound, app.auth.GetOIDCAuthURL(next, nonce.Value))
state := oidcState{
Nonce: nonce.Value,
Next: next,
}

stateJSON, err := json.Marshal(state)
if err != nil {
app.log.Printf("error marshalling OIDC state: %v", err)
return echo.NewHTTPError(http.StatusInternalServerError, app.i18n.T("globals.messages.internalError"))
}

return c.Redirect(http.StatusFound, app.auth.GetOIDCAuthURL(base64.URLEncoding.EncodeToString(stateJSON), nonce.Value))
}

// handleOIDCFinish receives the redirect callback from the OIDC provider and completes the handshake.
Expand All @@ -125,6 +143,21 @@ func handleOIDCFinish(c echo.Context) error {
return renderLoginPage(c, err)
}

// Validate the state.
var state oidcState
stateB, err := base64.URLEncoding.DecodeString(c.QueryParam("state"))
if err != nil {
app.log.Printf("error decoding OIDC state: %v", err)
return echo.NewHTTPError(http.StatusInternalServerError, app.i18n.T("globals.messages.internalError"))
}
if err := json.Unmarshal(stateB, &state); err != nil {
app.log.Printf("error unmarshalling OIDC state: %v", err)
return echo.NewHTTPError(http.StatusInternalServerError, app.i18n.T("globals.messages.internalError"))
}
if state.Nonce != nonce.Value {
return renderLoginPage(c, echo.NewHTTPError(http.StatusUnauthorized, app.i18n.T("users.invalidRequest")))
}

// Validate e-mail from the claim.
email := strings.TrimSpace(claims.Email)
if email == "" {
Expand Down Expand Up @@ -153,7 +186,7 @@ func handleOIDCFinish(c echo.Context) error {
return renderLoginPage(c, err)
}

return c.Redirect(http.StatusFound, utils.SanitizeURI(c.QueryParam("state")))
return c.Redirect(http.StatusFound, utils.SanitizeURI(state.Next))
}

// renderLoginPage renders the login page and handles the login form.
Expand Down
3 changes: 0 additions & 3 deletions cmd/init.go
Original file line number Diff line number Diff line change
Expand Up @@ -434,9 +434,6 @@ func initConstants() *constants {
c.BounceSendgridEnabled = ko.Bool("bounce.sendgrid_enabled")
c.BouncePostmarkEnabled = ko.Bool("bounce.postmark.enabled")
c.BounceForwardemailEnabled = ko.Bool("bounce.forwardemail.enabled")

fmt.Println(c.BounceForwardemailEnabled)

c.HasLegacyUser = ko.Exists("app.admin_username") || ko.Exists("app.admin_password")

b := md5.Sum([]byte(time.Now().String()))
Expand Down

0 comments on commit abe09d6

Please # to comment.