Page MenuHomePhabricator

jwt.io shows owner-only tokens with an invalid "exp" claim date
Closed, DeclinedPublic

Description

When I generate an owner-only OAuth 2.0 token, the "exp" claim is very far in the future (billions of years, maybe?). jwt.io shows the value as an "invalid date".

I'm not sure if other JWT processors mishandle the value, but it might be nice to bring the "far future" value down to a number that jwt.io thinks is valid. I could get it to work with a 12-digit number but it gives an invalid date error with a 13-digit number. Given that a value of 999999999999 is 30,000 years in the future, that'd probably be sufficiently close to "forever" to be useful.

(Deepest apologies to the engineer who is debugging this on September 26, 33658 when all the owner-only access tokens stop working.)

Event Timeline

@Anomie I opened a second low-priority bug for the "invalid date" in "exp".

Declining this for several reasons:

  1. The fact that these tokens are a JWT is a private implementation detail (and one I'd actually like to change, see some background on T244393). RFC 6749 § 1.4 specifies "The string is usually opaque to the client". As long as MediaWiki accepts the tokens that it itself generates, we're fine.
  2. I note that jwt.io isn't claiming the JWT is invalid, it's just failing to convert the value to a date.
  3. Such an expiry does not seem to actually be invalid JWT either. Specifically, RFC 7519 § 4.1.4 specifies only that "Its value MUST be a number containing a NumericDate value." NumericDate is defined on page 6 as "A JSON numeric value representing the number of seconds [...]". Neither POSIX.1 (here?) nor RFC 3339 that it references specifies a range on the upper end. So as a number of seconds, it's valid. For the "JSON numeric value" part of the definition, RFC 7159 § 6 similarly doesn't declare a limit on valid values.

As long as MediaWiki accepts the tokens that it itself generates, we're fine.

This is not strictly true. As we begin implementing APIs in services outside MediaWiki, we'll be depending on these JWTs for authentication, and they won't be opaque.

I think this is a problem with the JavaScript Date class, which I guess can convert integers to dates at about this scale (100,000,000 days, per the Mozilla page). Since we have often done external API services in NodeJS, I'd like to see this corrected.

Also, I'm a -2 on changing from JWTs. They have a lot of useful properties.

Anomie closed this task as Declined.EditedFeb 6 2020, 5:58 PM

A client that wants a JWT should use the /oauth2/resource/profile endpoint (or some similar endpoint) rather than trying to interpret the access token. The token is supposed to be opaque.

I think that specific endpoint may not currently return a JWT, just the payload that might be in a JWT, but that could easily enough be fixed or a new endpoint added. OAuth 1.0a has an endpoint at Special:OAuth/identify that does return an actual JWT.