azure-activedirectory-identitymodel-extensions-for-dotnet icon indicating copy to clipboard operation
azure-activedirectory-identitymodel-extensions-for-dotnet copied to clipboard

Parsing/Validating a JWT token with invalid `exp` field fails on core 31.

Open blowdart opened this issue 4 years ago • 12 comments

From https://github.com/dotnet/aspnetcore/issues/25419

Bug description

JwtPayload.Exp throws if tokens contains a DateTIme instead of numeric value

Expected behavioud

It should return null

Details

The documentation of System.IdentityModel.Tokens.Jwt.JwtPayload.Exp states :

If the 'expiration' claim is not found OR could not be converted to <, null is returned.

However this is not the case. Exp property geter throws an exception if values is a Datetime. Here is a sample token

{
  "exp": "2020-09-08T21:18:18.5297739+02:00",
  "name": "tojename"
}

Please note that the payload is incorrect (exp should be a numeric type as per https://tools.ietf.org/html/rfc7519#section-4.1.4)

The JwtPayload.GetIntClaim() tires exception of type FormatException, InvalidCastException and OverflowException, but it does not handle InvalidCastException which is thrown by DateTime.IConvertible.ToDouble

My scenario is interop with some legacy service that created invalid token. This is not critical issue for me, I am just pointing out inconsistency in implementation/documentation.

The implementation ignores exp if it sets to "foo", but not if it set to a DateTime. The documentation states that invalid values are ignored, but they are not for DaateTime.

blowdart avatar Aug 31 '20 18:08 blowdart

@matra774

blowdart avatar Aug 31 '20 18:08 blowdart

Thanks @matra774 for reporting this.

@brentschmaltz do we want to get this into 6.7.3 or 6.7.3 +1?

keegan-caruso avatar Aug 31 '20 19:08 keegan-caruso

@blowdart @keegan-caruso @matra774 it looks like our documentation is incorrect. The exp, iat, nbf claims should be NumericDate https://tools.ietf.org/html/rfc7519#section-4.1.4 . We should be throwing.

It would be prudent to ensure that JsonWebToken and JwtSecurityToken handle the same dates in the same way.

brentschmaltz avatar Sep 02 '20 00:09 brentschmaltz

it looks like our documentation is incorrect.

Not just the docs, the implementation also. All incorrect data should be handled in the same way (now string are handled differently than DateTime when NumerDate is expected)

matra774 avatar Sep 02 '20 13:09 matra774

@matra774 yes i agree a "DateTime" such as "2020-09-08T21:18:18.5297739+02:00" is not NumericDate. However, if we modify this behavior and throw, we may break users.

brentschmaltz avatar Sep 02 '20 14:09 brentschmaltz

@brentschmaltz I do not suggest to modify the behavior so that exp property getter throws. On a contrary. It currently throws, if a value is DateTime string - I suggest that it should NOT throw (as is the case if you use "foo" as the value for exp)

On a related note. The exp property currently returns int32 making it prone to year 2038 problem.

Currently token with high expiry dates behaves as if there is no exp field in the token. If you try to validate such token you will get exception IDX10225: Lifetime validation failed. The token is missing an Expiration Time.

Sample token: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiI1IiwibmJmIjoxNTk5NDExNDkxLCJleHAiOjIyMDQyMTE0OTEsImlhdCI6MTU5OTQxMTQ5MSwiaXNzIjoiaHR0cDovL215c2l0ZS5jb20iLCJhdWQiOiJodHRwOi8vbXlhdWRpZW5jZS5jb20ifQ.sXIRrKBgdnRfm2YLQnSn9fOcl3RGyXXpagkF9Z4jKno

matra774 avatar Sep 06 '20 17:09 matra774

@brentschmaltz I am getting a token exception message like this, is it related to this one. My token is valid and exp value is 1599280362

"IDX10223: Lifetime validation failed. The token is expired. ValidTo: 'System.DateTime', Current time: 'System.DateTime'."

divyanshumehta avatar Sep 09 '20 17:09 divyanshumehta

@divyanshumehta

By default all parameters are censored. To show the parameters (potential PII) see:

https://github.com/AzureAD/azure-activedirectory-identitymodel-extensions-for-dotnet/wiki/PII

keegan-caruso avatar Sep 09 '20 17:09 keegan-caruso

ohh sorry I looked into it, i think since I am +3 hours from UTC that is why the token is always showing expired.

divyanshumehta avatar Sep 09 '20 17:09 divyanshumehta

@matra774 i agree we have 2038 issue and will have to add a new API, so we don't break backcompat.

@keegan-caruso i see a couple of issues with out GetIntClaim to handle 'exp', 'iat', 'nbf'

  1. Should we be allowing an array?
  2. we should not be throwing if we can't be converting to int.

brentschmaltz avatar Sep 29 '20 20:09 brentschmaltz

@divyanshumehta

By default all parameters are censored. To show the parameters (potential PII) see:

https://github.com/AzureAD/azure-activedirectory-identitymodel-extensions-for-dotnet/wiki/PII

@keegan-caruso This problem that @divyanshumehta reported, the only way to show the date would be setting this flag to true, right? Because if this exception is throw, in production environment the date will always be hidden, since doesn't make sense to show PII in production environments.

jairofranchi avatar Mar 31 '21 17:03 jairofranchi

@jairofranchi assigning this to @sruke.

brentschmaltz avatar Nov 04 '21 21:11 brentschmaltz

fixed in IdentityModel 7

jennyf19 avatar Sep 11 '23 00:09 jennyf19