Skip to content

Commit

Permalink
Fix for exp claim considered valid if equal to now (#652)
Browse files Browse the repository at this point in the history
exp claim cannot be equal to now
  • Loading branch information
jimmyjames committed Jan 26, 2023
1 parent 6e80ea1 commit 12ae664
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 7 deletions.
6 changes: 3 additions & 3 deletions lib/src/main/java/com/auth0/jwt/JWTVerifier.java
Original file line number Diff line number Diff line change
Expand Up @@ -346,7 +346,7 @@ private boolean assertValidInstantClaim(String claimName, Claim claim, long leew
throw new TokenExpiredException(String.format("The Token has expired on %s.", claimVal), claimVal);
}
} else {
isValid = assertInstantIsPast(claimVal, leeway, now);
isValid = assertInstantIsLessThanOrEqualToNow(claimVal, leeway, now);
if (!isValid) {
throw new IncorrectClaimException(
String.format("The Token can't be used before %s.", claimVal), claimName, claim);
Expand All @@ -356,10 +356,10 @@ private boolean assertValidInstantClaim(String claimName, Claim claim, long leew
}

private boolean assertInstantIsFuture(Instant claimVal, long leeway, Instant now) {
return !(claimVal != null && now.minus(Duration.ofSeconds(leeway)).isAfter(claimVal));
return claimVal == null || now.minus(Duration.ofSeconds(leeway)).isBefore(claimVal);
}

private boolean assertInstantIsPast(Instant claimVal, long leeway, Instant now) {
private boolean assertInstantIsLessThanOrEqualToNow(Instant claimVal, long leeway, Instant now) {
return !(claimVal != null && now.plus(Duration.ofSeconds(leeway)).isBefore(claimVal));
}

Expand Down
5 changes: 3 additions & 2 deletions lib/src/test/java/com/auth0/jwt/JWTTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
import java.security.interfaces.ECKey;
import java.security.interfaces.RSAKey;
import java.time.Clock;
import java.time.Duration;
import java.time.Instant;
import java.time.ZoneId;
import java.util.Base64;
Expand Down Expand Up @@ -270,12 +271,12 @@ public void shouldGetStringAudience() {
@Test
public void shouldGetExpirationTime() {
long seconds = 1477592L;
Clock clock = Clock.fixed(Instant.ofEpochSecond(seconds), ZoneId.of("UTC"));
Clock mockNow = Clock.fixed(Instant.ofEpochSecond(seconds - 1), ZoneId.of("UTC"));

String token = "eyJhbGciOiJIUzI1NiJ9.eyJleHAiOjE0Nzc1OTJ9.x_ZjkPkKYUV5tdvc0l8go6D_z2kez1MQcOxokXrDc3k";
JWTVerifier.BaseVerification verification = (JWTVerifier.BaseVerification) JWT.require(Algorithm.HMAC256("secret"));
DecodedJWT jwt = verification
.build(clock)
.build(mockNow)
.verify(token);

assertThat(jwt, is(notNullValue()));
Expand Down
30 changes: 28 additions & 2 deletions lib/src/test/java/com/auth0/jwt/JWTVerifierTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -657,6 +657,7 @@ public void shouldThrowOnNegativeCustomLeeway() {
}

// Expires At

@Test
public void shouldValidateExpiresAtWithLeeway() {
String token = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE0Nzc1OTJ9.isvT0Pqx0yjnZk53mUFSeYFJLDs-Ls9IsNAm86gIdZo";
Expand All @@ -674,12 +675,26 @@ public void shouldValidateExpiresAtIfPresent() {
String token = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE0Nzc1OTJ9.isvT0Pqx0yjnZk53mUFSeYFJLDs-Ls9IsNAm86gIdZo";
JWTVerifier.BaseVerification verification = (JWTVerifier.BaseVerification) JWTVerifier.init(Algorithm.HMAC256("secret"));
DecodedJWT jwt = verification
.build(mockNow)
.build(mockOneSecondEarlier)
.verify(token);

assertThat(jwt, is(notNullValue()));
}

@Test
public void shouldThrowWhenExpiresAtIsNow() {
// exp must be > now
TokenExpiredException e = assertThrows(null, TokenExpiredException.class, () -> {
String token = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE0Nzc1OTJ9.isvT0Pqx0yjnZk53mUFSeYFJLDs-Ls9IsNAm86gIdZo";
JWTVerifier.BaseVerification verification = (JWTVerifier.BaseVerification) JWTVerifier.init(Algorithm.HMAC256("secret"));
verification
.build(mockNow)
.verify(token);
});
assertThat(e.getMessage(), is("The Token has expired on 1970-01-18T02:26:32Z."));
assertThat(e.getExpiredOn(), is(Instant.ofEpochSecond(1477592L)));
}

@Test
public void shouldThrowOnInvalidExpiresAtIfPresent() {
TokenExpiredException e = assertThrows(null, TokenExpiredException.class, () -> {
Expand Down Expand Up @@ -731,7 +746,18 @@ public void shouldThrowOnInvalidNotBeforeIfPresent() {

@Test
public void shouldValidateNotBeforeIfPresent() {
String token = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE0Nzc1OTJ9.isvT0Pqx0yjnZk53mUFSeYFJLDs-Ls9IsNAm86gIdZo";
String token = "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJuYmYiOjE0Nzc1OTN9.f4zVV0TbbTG5xxDjSoGZ320JIMchGoQCWrnT5MyQdT0";
JWTVerifier.BaseVerification verification = (JWTVerifier.BaseVerification) JWTVerifier.init(Algorithm.HMAC256("secret"));
DecodedJWT jwt = verification
.build(mockOneSecondLater)
.verify(token);

assertThat(jwt, is(notNullValue()));
}

@Test
public void shouldAcceptNotBeforeEqualToNow() {
String token = "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJuYmYiOjE0Nzc1OTJ9.71XBtRmkAa4iKnyhbS4NPW-Xr26eAVAdHZgmupS7a5o";
JWTVerifier.BaseVerification verification = (JWTVerifier.BaseVerification) JWTVerifier.init(Algorithm.HMAC256("secret"));
DecodedJWT jwt = verification
.build(mockNow)
Expand Down

0 comments on commit 12ae664

Please sign in to comment.