paseto-standard / paseto-spec

Specification for Platform Agnostic SEcurity TOkens (PASETO)
165 stars 9 forks source link

Specification is too Broad for Reserved Claims of DateTime Type #25

Closed IamfromSpace closed 2 years ago

IamfromSpace commented 2 years ago

Hello, I've been looking into implementing the PASeTo spec in Haskell, and I noticed that this line is impractical in its current form:

...DateTime means an ISO 8601 compliant DateTime string.

ISO 8601 is very broad and flexible, so truly implement this would be a fairly major burden (if not impossible, since arbitrary formatting is possible). On top of this, ISO 8601 allows for specifying dates in ways that simply don't make sense, like local date times, in which case one must know where the signer was in the world. It seems clear that none of this is intentional, and that tightening this down to a specific profile of ISO 8601 would better.

Personally, I would recommend that in PASeTo's spirit of preventing misuse, the only format allowed is "yyyy-mm-ddThh:mm:ss[.sss]Z" from ISO 8601:2004(E) section 4.3.2. This is a common format for an unambiguous instant or moment in time that is independent from a location in the world. Since Time Zones are a frequent area of misunderstanding, and this is an area where they can be avoided all together, they should be avoided.

Since current spec examples do include TZ offsets, if folks feel that needs to be preserved, then it makes sense to also allow for "yyyy-mm-ddThh:mm:ss[.sss]±hh:mm" (from the same section of the standard). Ideally, where only "±00:00" is allowed. Should other offsets be allowed, it would be worth considering to explicitly state that the offset itself should carry no meaning beyond determining the correct instant in time.

I'd be glad to make a PR if a general approach was nailed down.

Cheers!

paragonie-security commented 2 years ago

Yes. The intent was based on PHP's DateTimeInterface::ISO8601.

IamfromSpace commented 2 years ago

Makes sense!

Also interesting that despite the name, it isn't quite right:

Note: This format is not compatible with ISO-8601, but is left this way for backward compatibility reasons. Use DateTime::ATOM or DATE_ATOM for compatibility with ISO-8601 instead.

The examples given correspond to DateTimeInterface::ATOM, which is probably good.

Thinking about this more, I think we should go for RFC 3339, section 5.6, Internet Date/Time Format. That means the examples are still correct and libs should be readily available without too much fiddling. For PHP DateTimeInterface::RFC3339 is a synonym for DateTimeInterface::ATOM, and then either DateTimeInterface::RFC3339_EXTENDED need also be supported (unless it treats the fractional seconds as optional, in which case, it's the only format that need be considered).

I'll draw up a PR and we can get into the details.