mirror of
https://github.com/OffchainLabs/prysm.git
synced 2026-01-10 07:58:22 -05:00
Validate JWT Signing Type in RPC (#7576)
* validate jwt signing type * lint * gaz Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com> Co-authored-by: Preston Van Loon <preston@prysmaticlabs.com>
This commit is contained in:
@@ -73,6 +73,7 @@ go_test(
|
||||
"//shared/testutil:go_default_library",
|
||||
"//shared/testutil/assert:go_default_library",
|
||||
"//shared/testutil/require:go_default_library",
|
||||
"//shared/timeutils:go_default_library",
|
||||
"//validator/accounts:go_default_library",
|
||||
"//validator/accounts/wallet:go_default_library",
|
||||
"//validator/client:go_default_library",
|
||||
@@ -81,6 +82,7 @@ go_test(
|
||||
"//validator/keymanager:go_default_library",
|
||||
"//validator/keymanager/derived:go_default_library",
|
||||
"//validator/keymanager/imported:go_default_library",
|
||||
"@com_github_dgrijalva_jwt_go//:go_default_library",
|
||||
"@com_github_gogo_protobuf//types:go_default_library",
|
||||
"@com_github_google_uuid//:go_default_library",
|
||||
"@com_github_prysmaticlabs_ethereumapis//eth/v1alpha1:go_default_library",
|
||||
|
||||
@@ -2,6 +2,7 @@ package rpc
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
@@ -60,16 +61,20 @@ func (s *Server) authorize(ctx context.Context) error {
|
||||
if !ok {
|
||||
return status.Errorf(codes.Unauthenticated, "Authorization token could not be found")
|
||||
}
|
||||
checkParsedKey := func(*jwt.Token) (interface{}, error) {
|
||||
return s.jwtKey, nil
|
||||
}
|
||||
if len(authHeader) < 1 || !strings.Contains(authHeader[0], "Bearer ") {
|
||||
return status.Error(codes.Unauthenticated, "Invalid auth header, needs Bearer {token}")
|
||||
}
|
||||
token := strings.Split(authHeader[0], "Bearer ")[1]
|
||||
_, err := jwt.Parse(token, checkParsedKey)
|
||||
_, err := jwt.Parse(token, s.validateJWT)
|
||||
if err != nil {
|
||||
return status.Errorf(codes.Unauthenticated, "Could not parse JWT token: %v", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *Server) validateJWT(token *jwt.Token) (interface{}, error) {
|
||||
if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok {
|
||||
return nil, fmt.Errorf("unexpected JWT signing method: %v", token.Header["alg"])
|
||||
}
|
||||
return s.jwtKey, nil
|
||||
}
|
||||
|
||||
@@ -4,7 +4,9 @@ import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"github.com/dgrijalva/jwt-go"
|
||||
"github.com/prysmaticlabs/prysm/shared/testutil/require"
|
||||
"github.com/prysmaticlabs/prysm/shared/timeutils"
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/grpc/metadata"
|
||||
)
|
||||
@@ -58,3 +60,14 @@ func TestServer_JWTInterceptor_BadToken(t *testing.T) {
|
||||
_, err = interceptor(ctx, "xyz", unaryInfo, unaryHandler)
|
||||
require.ErrorContains(t, "signature is invalid", err)
|
||||
}
|
||||
|
||||
func TestServer_JWTInterceptor_InvalidSigningType(t *testing.T) {
|
||||
ss := &Server{jwtKey: make([]byte, 32)}
|
||||
expirationTime := timeutils.Now().Add(tokenExpiryLength)
|
||||
// Use a different signing type than the expected, HMAC.
|
||||
token := jwt.NewWithClaims(jwt.SigningMethodRS256, jwt.StandardClaims{
|
||||
ExpiresAt: expirationTime.Unix(),
|
||||
})
|
||||
_, err := ss.validateJWT(token)
|
||||
require.ErrorContains(t, "unexpected JWT signing method", err)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user