Skip to content

Example for jwt.Parse uses incorrect method for validating algorithm methods #424

Closed
@mattt

Description

@mattt

The ExampleParse_hmac function in hmac_example_test.go provides the following example code:

jwt/hmac_example_test.go

Lines 51 to 59 in bc8bdca

token, err := jwt.Parse(tokenString, func(token *jwt.Token) (interface{}, error) {
// Don't forget to validate the alg is what you expect:
if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok {
return nil, fmt.Errorf("Unexpected signing method: %v", token.Header["alg"])
}
// hmacSampleSecret is a []byte containing your secret, e.g. []byte("my_secret_key")
return hmacSampleSecret, nil
})

The validation performed on line 53 seems at odds with the recommendations in the Parse function docs:

jwt/parser.go

Lines 218 to 225 in bc8bdca

// Parse parses, validates, verifies the signature and returns the parsed token.
// keyFunc will receive the parsed token and should return the cryptographic key
// for verifying the signature. The caller is strongly encouraged to set the
// WithValidMethods option to validate the 'alg' claim in the token matches the
// expected algorithm. For more details about the importance of validating the
// 'alg' claim, see
// https://auth0.com/blog/critical-vulnerabilities-in-json-web-token-libraries/
func Parse(tokenString string, keyFunc Keyfunc, options ...ParserOption) (*Token, error) {

In this case, the type assertion tests whether token.Method can be safely converted to the *jwt.SigningMethodHMAC type. But a more specific check for HS256 seems more appropriate.

token, err := jwt.Parse(tokenString, func(token *jwt.Token) (interface{}, error) {
	// hmacSampleSecret is a []byte containing your secret, e.g. []byte("my_secret_key")
	return hmacSampleSecret, nil
}, jwt.WithValidMethods([]string{jwt.SigningMethodHS256.Alg()}))

Or for all HMAC signing methods:

validMethods := []string{
	jwt.SigningMethodHS256.Alg(),
	jwt.SigningMethodHS384.Alg(),
	jwt.SigningMethodHS512.Alg(),
}
token, err := jwt.Parse(tokenString, func(token *jwt.Token) (interface{}, error) {
	// hmacSampleSecret is a []byte containing your secret, e.g. []byte("my_secret_key")
	return hmacSampleSecret, nil
}, jwt.WithValidMethods(validMethods))

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions