delight-im / PHP-Auth

Authentication for PHP. Simple, lightweight and secure.
MIT License
1.09k stars 235 forks source link

InvalidSelectorTokenPairException on every attempt to change password #292

Closed triumphhub closed 1 year ago

triumphhub commented 1 year ago

Hello,

This issue started recently. Every time a user tries to change their password, the error "InvalidSelectorTokenPairException" comes up.

The url created from the server for the user is:

$auth->forgotPassword($_POST['inputEmail'], function ($selector, $token) {
$url = 'http://'.$_SERVER['HTTP_HOST'].'/reset_password.php?selector=' . \urlencode($selector) . '&token=' . \urlencode($token) . ';
....

The actual url: http://xxxxxxxxx.com/reset_password.php?selector=h4_TQx3L8tF6yS8l1kuh&token=YQZPRVdDI007F150SwCb

The token: $2a$04$PUiVUG2znNBpgunuwyEM0u/ZykOa0Bh1.QtmtpCrBGH.OXMFFPUIa

The selector works fine but the token fails.

Any help is appreciated.

ocram commented 1 year ago

Thank you!

The specific URL doesn’t really matter, as long as you feed the selector and token to the correct method on the Auth instance again in the next step. Which is what you do and have always done, I assume.

Apart from that, what you’re saying is that you can find the selector in the database yourself, in the table for the reset data, but the token is wrong? Can you verify it manually with PHP’s built-in password_verify function?

In general, did you modify any of your database tables, update your database software or upgrade your PHP version lately?

triumphhub commented 1 year ago

Thank you for the quick response. I'm pretty sure nothing you mentioned has been changed but I'll verify and check with password verify.

Thanks

triumphhub commented 1 year ago

When I put the selector and Token into password_verify, I get an "invalid password" response.

triumphhub commented 1 year ago

UPDATE: This is where I have got so far: I have confirmed I have the latest version in composer (v8.3.0) When verifying the selector and token from the db, it fails using the function password_verify($pass, $hash). I can get the password_verify to validate if I change Line 1203 in Auth.php From $tokenHashed = \password_hash($token, \PASSWORD_DEFAULT); To $tokenHashed = \password_hash($selector, \PASSWORD_DEFAULT);

This no longer gives an "InvalidSelectorTokenPairException" but now I have a password expired error. I'll try to test that next.

triumphhub commented 1 year ago

The above-expired message was in fact an issue with the canResetPasswordOrThrow due to changing line 1203. Any suggestions on a different approach such as how to rollback to a previous version?

triumphhub commented 1 year ago

This is what os throwing the Error: try { $auth->canResetPasswordOrThrow($_GET['selector'], $_GET['token']);

echo 'Put the selector into a "hidden" field (or keep it in the URL)';
echo 'Put the token into a "hidden" field (or keep it in the URL)';

echo 'Ask the user for their new password';

} catch (\Delight\Auth\InvalidSelectorTokenPairException $e) { die('Invalid token'); }

Any ideas how to test what it is trying to do with the $selector and $token?

triumphhub commented 1 year ago

I couldn't resolve nor find any issue, but rolling back to a previous backup of the site fixed it.