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:
Raul Jordan
2020-10-20 00:37:12 -05:00
committed by GitHub
parent ec0af98a9e
commit 816eb94adf
3 changed files with 24 additions and 4 deletions

View File

@@ -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",

View File

@@ -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
}

View File

@@ -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)
}