octanner/rack-auth-oc_tanner — pull request #24 by jaywagnon (2014-07-08 16:27:34+00:00)
Title: Fix SmD bounds

The SmallDate (SmD) module has a known roll-over issue in its date representation. In short, when the value representing the dates reaches its maximum, it rolls-over back to zero. In the default configuration (i.e. dates are represented at an hourly level in two-bytes), this occurs every seven-and-a-half years or so; the next roll-over date based on the January 1, 1970 epoch is November 10th, 2014.

For token expiration checks, this is a problem. Ideally, the expiration dates in OAuth would be fully represented to avoid roll-over issue entirely. However, the current token format does not support this (my understanding is that it is to compress token size to better support mobile client messaging limitations). So, using the SmD representation, when the server doing the validation is in the one SmD range but the token being checked is set to expire is in the next SmD range, then it'll appear that the token is really, really old and the validation will fail.

Best practice is to have tokens with very short expiration dates (e.g. an hour or two, max). However, many services have take short-cuts around token acquisition by generation month- or even year-long tokens. Any newly generated tokens with these expiration ranges will begin to fail the closer we get to the November 10th, 2014.

These changes try to mitigate this problem by presuming that validations that occur close to the roll-over point are valid, even if the token appears to be expired. This is a weakening of the validation; technically, a very old token that is actually expired would be treated as valid. However, it's difficult to determine which expiration dates are "real" and which are "old" without making arbitrary decisions about what "old" means. For now, these changes are a kind of stop-gap measure to hold us over until November. After that, all servers and clients should be in the next SmD range, and we'll be "good" for another seven years.