Skip to content

Token verification may fail for DateTime instances with milliseconds resolution #259

@spetters

Description

@spetters

In our project we had issues with wrong password reset requests. We were able to track this down to a rounding issue with the expiresAt field for the ResetPasswordRequest.

Setup:
Symfony 6.2.6
PHP 8.1.13
Doctrine MySQL

For the hashed token, the unix timestamp of the expiresAt is used and stored. Also expiresAt is stored as DateTimeImmutable. With Doctrine entries with milliseconds will get rounded and stored with an one second higher value in the database.

During verification based on the expiresAt value, the hashes then do not match and the user is confronted with an error.

Our solution is to strip the milliseconds while creating a ResetPasswordRequest:

...
class ResetPasswordRequest implements ResetPasswordRequestInterface {

	use ResetPasswordRequestTrait;

	...

	public function __construct(User $user, \DateTimeInterface $expiresAt, string $selector, string $hashedToken) {
		$this->user = $user;

		// strip milliseconds
		$mutable = \DateTime::createFromInterface($expiresAt);
		$mutable->setTime(
			(int) $expiresAt->format('G'),
			(int) $expiresAt->format('i'),
			(int) $expiresAt->format('s')
		);

		$this->initialize($mutable, $selector, $hashedToken);
	}
...

This could be added to the maker script.

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