From c359fdc83faa9863778dab21768db6d695d768e8 Mon Sep 17 00:00:00 2001 From: Lakhan Samani Date: Fri, 3 Apr 2026 21:15:12 +0530 Subject: [PATCH] fix(token): use safe type assertions for JWT claims Unguarded type assertions like claims["sub"].(string) panic if the claim is missing or the wrong type. An attacker could craft a valid- signature token with missing claims to crash the server. Replaced with comma-ok pattern in ValidateAccessToken, ValidateRefreshToken, and GetUserIDFromSessionOrAccessToken. Fixes: H2 (High) --- internal/token/auth_token.go | 38 ++++++++++++++++++++++++------------ 1 file changed, 25 insertions(+), 13 deletions(-) diff --git a/internal/token/auth_token.go b/internal/token/auth_token.go index 8128c2db..74f551e5 100644 --- a/internal/token/auth_token.go +++ b/internal/token/auth_token.go @@ -254,13 +254,16 @@ func (p *provider) ValidateAccessToken(gc *gin.Context, accessToken string) (map return res, err } - userID := res["sub"].(string) - nonce := res["nonce"].(string) + userID, ok := res["sub"].(string) + if !ok || userID == "" { + return res, fmt.Errorf(`unauthorized: missing sub claim`) + } + nonce, _ := res["nonce"].(string) - loginMethod := res["login_method"] + loginMethod, _ := res["login_method"].(string) sessionKey := userID - if loginMethod != nil && loginMethod != "" { - sessionKey = loginMethod.(string) + ":" + userID + if loginMethod != "" { + sessionKey = loginMethod + ":" + userID } token, err := p.dependencies.MemoryStoreProvider.GetUserSession(sessionKey, constants.TokenTypeAccessToken+"_"+nonce) @@ -303,13 +306,16 @@ func (p *provider) ValidateRefreshToken(gc *gin.Context, refreshToken string) (m return res, err } - userID := res["sub"].(string) - nonce := res["nonce"].(string) + userID, ok := res["sub"].(string) + if !ok || userID == "" { + return res, fmt.Errorf(`unauthorized: missing sub claim`) + } + nonce, _ := res["nonce"].(string) - loginMethod := res["login_method"] + loginMethod, _ := res["login_method"].(string) sessionKey := userID - if loginMethod != nil && loginMethod != "" { - sessionKey = loginMethod.(string) + ":" + userID + if loginMethod != "" { + sessionKey = loginMethod + ":" + userID } token, err := p.dependencies.MemoryStoreProvider.GetUserSession(sessionKey, constants.TokenTypeRefreshToken+"_"+nonce) if nonce == "" || err != nil { @@ -509,9 +515,15 @@ func (p *provider) GetUserIDFromSessionOrAccessToken(gc *gin.Context) (*SessionO p.dependencies.Log.Debug().Err(err).Msg("Failed to validate access token") return nil, fmt.Errorf(`unauthorized`) } + userID, ok := claims["sub"].(string) + if !ok || userID == "" { + return nil, fmt.Errorf(`unauthorized: missing sub claim`) + } + loginMethod, _ := claims["login_method"].(string) + nonce, _ := claims["nonce"].(string) return &SessionOrAccessTokenData{ - UserID: claims["sub"].(string), - LoginMethod: claims["login_method"].(string), - Nonce: claims["nonce"].(string), + UserID: userID, + LoginMethod: loginMethod, + Nonce: nonce, }, nil }