Passkeys are not deleted when a user

Xon

Well-known member
Affected version
2.3.7
XF\Service\Passkey\ManagerService::getPasskeyUser() can return null, which will cause internal server errors due to various login methods requiring a user entity.

The validate function should be checking that the user exists, or the simple way would be to add ->with('User', true) when fetching passKey record.

ie something like:
PHP:
$this->passkey = \XF::app()->finder(PasskeyFinder::class)
->with('User', true)
->where('credential_id', $credentialId)
->fetchOne();

Additionally, the xf_passkey entries for a user should be purged when that user is deleted. Both changes are probably required for correctness; not just deleting the user's passkey records.
 
If passkeys are going to be deleted, probably need an XF installer step to cleanup the data. For any users being affected by this bug, this query should clean things up:
SQL:
DELETE
FROM xf_passkey
WHERE user_id NOT IN (SELECT user_id FROM xf_user)
 
Could be wrong, but if we get a cleanup query, I would expect the following to be more performant, since it doesn't involve a subquery with a full scan on xf_user, just the full scan on xf_passkey:
Code:
DELETE passkey
FROM xf_passkey AS passkey
LEFT JOIN xf_user AS user ON (passkey.user_id = user.user_id)
WHERE user.user_id IS NULL
It seems like xf_passkey should be the smaller table, so the one we would prefer to scan and generate a temporary table from.
 
Last edited:
Modern-ish mysql can be kinda wonky on which is more or less performance for that sort of query. A basic not in like that should get transformed into a similar execution plan as left join is null.
 
Back
Top Bottom