From 4c5f7c79e7b14ca7970ef624a0738ae52a045c45 Mon Sep 17 00:00:00 2001 From: Lakhan Samani Date: Fri, 3 Apr 2026 21:13:04 +0530 Subject: [PATCH] fix(token): verify JWT algorithm in parse keyfunc The keyfunc never validated token.Method against the expected signing method, enabling JWT algorithm confusion attacks where an attacker could craft a token using a different algorithm (e.g., HMAC with the public key as secret) to bypass signature verification. Now each keyfunc verifies the token's algorithm matches the configured signing method before returning the verification key. Fixes: H1 (High) --- internal/token/jwt.go | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/internal/token/jwt.go b/internal/token/jwt.go index 2608d882..63e19cf0 100644 --- a/internal/token/jwt.go +++ b/internal/token/jwt.go @@ -51,11 +51,17 @@ func (p *provider) ParseJWTToken(token string) (jwt.MapClaims, error) { var err error switch signingMethod { case jwt.SigningMethodHS256, jwt.SigningMethodHS384, jwt.SigningMethodHS512: - _, err = jwt.ParseWithClaims(token, &claims, func(token *jwt.Token) (interface{}, error) { + _, err = jwt.ParseWithClaims(token, &claims, func(t *jwt.Token) (interface{}, error) { + if t.Method.Alg() != signingMethod.Alg() { + return nil, fmt.Errorf("unexpected signing method: %v", t.Header["alg"]) + } return []byte(p.config.JWTSecret), nil }) case jwt.SigningMethodRS256, jwt.SigningMethodRS384, jwt.SigningMethodRS512: - _, err = jwt.ParseWithClaims(token, &claims, func(token *jwt.Token) (interface{}, error) { + _, err = jwt.ParseWithClaims(token, &claims, func(t *jwt.Token) (interface{}, error) { + if t.Method.Alg() != signingMethod.Alg() { + return nil, fmt.Errorf("unexpected signing method: %v", t.Header["alg"]) + } key, err := crypto.ParseRsaPublicKeyFromPemStr(p.config.JWTPublicKey) if err != nil { return nil, err @@ -63,7 +69,10 @@ func (p *provider) ParseJWTToken(token string) (jwt.MapClaims, error) { return key, nil }) case jwt.SigningMethodES256, jwt.SigningMethodES384, jwt.SigningMethodES512: - _, err = jwt.ParseWithClaims(token, &claims, func(token *jwt.Token) (interface{}, error) { + _, err = jwt.ParseWithClaims(token, &claims, func(t *jwt.Token) (interface{}, error) { + if t.Method.Alg() != signingMethod.Alg() { + return nil, fmt.Errorf("unexpected signing method: %v", t.Header["alg"]) + } key, err := crypto.ParseEcdsaPublicKeyFromPemStr(p.config.JWTPublicKey) if err != nil { return nil, err