From 48ae3482e314857ac6086385579d503f11d67404 Mon Sep 17 00:00:00 2001 From: joshuaruesweg Date: Thu, 8 Sep 2022 20:27:45 +0200 Subject: [PATCH 1/3] Ensure numeric type of iat, nbf and exp parameters --- src/JWT.php | 44 ++++++++++++++++++++++++++++++++++---------- 1 file changed, 34 insertions(+), 10 deletions(-) diff --git a/src/JWT.php b/src/JWT.php index 9964073d..dc445355 100644 --- a/src/JWT.php +++ b/src/JWT.php @@ -142,24 +142,39 @@ public static function decode( // Check the nbf if it is defined. This is the time that the // token can actually be used. If it's not yet that time, abort. - if (isset($payload->nbf) && $payload->nbf > ($timestamp + static::$leeway)) { - throw new BeforeValidException( - 'Cannot handle token prior to ' . \date(DateTime::ISO8601, $payload->nbf) - ); + if (isset($payload->nbf)) { + if (!\is_int($payload->nbf)) { + throw new UnexpectedValueException('The property nbf must be of type integer.'); + } + if ($payload->nbf > ($timestamp + static::$leeway)) { + throw new BeforeValidException( + 'Cannot handle token prior to ' . \date(DateTime::ISO8601, $payload->nbf) + ); + } } // Check that this token has been created before 'now'. This prevents // using tokens that have been created for later use (and haven't // correctly used the nbf claim). - if (isset($payload->iat) && $payload->iat > ($timestamp + static::$leeway)) { - throw new BeforeValidException( - 'Cannot handle token prior to ' . \date(DateTime::ISO8601, $payload->iat) - ); + if (isset($payload->iat)) { + if (!\is_int($payload->iat)) { + throw new UnexpectedValueException('The property iat must be of type integer.'); + } + if ($payload->iat > ($timestamp + static::$leeway)) { + throw new BeforeValidException( + 'Cannot handle token prior to ' . \date(DateTime::ISO8601, $payload->iat) + ); + } } // Check if this token has expired. - if (isset($payload->exp) && ($timestamp - static::$leeway) >= $payload->exp) { - throw new ExpiredException('Expired token'); + if (isset($payload->exp)) { + if (!\is_int($payload->exp)) { + throw new UnexpectedValueException('The property exp must be of type integer.'); + } + if (($timestamp - static::$leeway) >= $payload->exp) { + throw new ExpiredException('Expired token'); + } } return $payload; @@ -194,6 +209,15 @@ public static function encode( if (isset($head) && \is_array($head)) { $header = \array_merge($head, $header); } + if (isset($payload['nbf']) && !\is_int($payload['nbf'])) { + throw new UnexpectedValueException('The property nbf must be an integer containing a unix timestamp.'); + } + if (isset($payload['iat']) && !\is_int($payload['iat'])) { + throw new UnexpectedValueException('The property nbf must be an integer containing a unix timestamp.'); + } + if (isset($payload['exp']) && !\is_int($payload['exp'])) { + throw new UnexpectedValueException('The property exp must be an integer containing a unix timestamp.'); + } $segments = []; $segments[] = static::urlsafeB64Encode((string) static::jsonEncode($header)); $segments[] = static::urlsafeB64Encode((string) static::jsonEncode($payload)); From ab2170dd458f43fea5e5cb6d7f26ae80c2639c92 Mon Sep 17 00:00:00 2001 From: joshuaruesweg Date: Thu, 8 Sep 2022 20:59:12 +0200 Subject: [PATCH 2/3] Add tests to ensure the numeric value of iat, nbf and exp parameters --- tests/JWTTest.php | 54 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) diff --git a/tests/JWTTest.php b/tests/JWTTest.php index 58c334ed..9d063367 100644 --- a/tests/JWTTest.php +++ b/tests/JWTTest.php @@ -394,4 +394,58 @@ public function testEncodeDecodeWithResource() $this->assertEquals('bar', $decoded->foo); } + + public function testEncodeExpectsIntegerIat() + { + $this->expectException(UnexpectedValueException::class); + $payload = [ + 'iat' => 'abc', + ]; + JWT::encode($payload, 'my_key', 'HS256'); + } + + public function testDecodeExpectsIntegerIat() + { + $this->expectException(UnexpectedValueException::class); + JWT::decode( + 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMzM3IiwibmFtZSI6IkpvaG4gU25vdyIsImlhdCI6InRlc3QifQ.B8cbURVQAPay3-Ep0DAm1Ji2rhij-hxfNA5PIDarf5o', + new Key('secret', 'HS256') + ); + } + + public function testEncodeExpectsIntegerNbf() + { + $this->expectException(UnexpectedValueException::class); + $payload = [ + 'nbf' => 'abc', + ]; + JWT::encode($payload, 'my_key', 'HS256'); + } + + public function testDecodeExpectsIntegerNbf() + { + $this->expectException(UnexpectedValueException::class); + JWT::decode( + 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMzM3IiwibmFtZSI6IkpvaG4gU25vdyIsIm5iZiI6InRlc3QifQ.9KdFz3ktQoPO5QFG3E7J86PEuw5Vmx0VPrUKszP7DDs', + new Key('secret', 'HS256') + ); + } + + public function testEncodeExpectsIntegerExp() + { + $this->expectException(UnexpectedValueException::class); + $payload = [ + 'exp' => 'abc', + ]; + JWT::encode($payload, 'my_key', 'HS256'); + } + + public function testDecodeExpectsIntegerExp() + { + $this->expectException(UnexpectedValueException::class); + JWT::decode( + 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMzM3IiwibmFtZSI6IkpvaG4gU25vdyIsImV4cCI6InRlc3QifQ.LXevvGvchI3PTBZo9jZ5-4d0OvONVU-_8Tbg_22-PTo', + new Key('secret', 'HS256') + ); + } } From 38a125aa566f36ec4a60f2d64cf278b5b4c64518 Mon Sep 17 00:00:00 2001 From: Brent Shaffer Date: Tue, 15 Apr 2025 14:56:55 -0700 Subject: [PATCH 3/3] Update src/JWT.php --- src/JWT.php | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/JWT.php b/src/JWT.php index b7385ad5..e8fc901f 100644 --- a/src/JWT.php +++ b/src/JWT.php @@ -227,9 +227,6 @@ public static function encode( if ($keyId !== null) { $header['kid'] = $keyId; } - if (isset($head) && \is_array($head)) { - $header = \array_merge($head, $header); - } if (isset($payload['nbf']) && !\is_int($payload['nbf'])) { throw new UnexpectedValueException('The property nbf must be an integer containing a unix timestamp.'); }