Skip to content

Date claims before the Unix epoch are rounded toward zero #806

Description

@znnnnnnn-wil

Checklist

  • I have looked into the README and Examples and have not found a suitable solution or answer.
  • I have looked into the API documentation and have not found a suitable solution or answer.
  • I have searched the issues and pull requests and have not found a duplicate.
  • I have searched the Auth0 Community forums and have not found a suitable solution or answer.
  • I agree to the terms within the Auth0 Code of Conduct.

Description

Date claims before the Unix epoch are converted to seconds using integer division, which truncates toward zero. This makes a Date and an Instant representing the same point in time serialize to different NumericDate values.

For example, new Date(-500) is half a second before the epoch. Its whole epoch second is -1, which is also returned by date.toInstant().getEpochSecond(). However, the Date serializer currently writes 0 because -500 / 1000 == 0 in Java.

Expected: equivalent Date and Instant values serialize to the same epoch second (-1).

Actual: the Date serializes to 0, while the equivalent Instant serializes to -1.

Reproduction

Date date = new Date(-500);
Instant instant = date.toInstant();

String token = JWT.create()
    .withClaim("date", date)
    .withClaim("instant", instant)
    .sign(Algorithm.none());

DecodedJWT decoded = JWT.decode(token);
System.out.println(decoded.getClaim("date").asLong());    // 0
System.out.println(decoded.getClaim("instant").asLong()); // -1

The inconsistency originates in ClaimsSerializer.dateToSeconds, which uses date.getTime() / 1000, while the Instant path uses Instant.getEpochSecond().

Additional context

Using floor division for millisecond-to-second conversion would make the Date path consistent with Instant for negative timestamps while leaving non-negative timestamps unchanged.

java-jwt version

4.6.1 (master at 29f252b)

Java version

Java 17.0.14

AI assistance disclosure: Codex assisted with identifying and structuring this report. The reproduction and analysis were reviewed and verified before submission.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

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