- Affected version
- 2.3.9
When a user attempts to register via a connected account at GitHub OAuth, and the chosen username already exists in
The registration form accepts the input, passes validation, and only fails at the
xf_user, XenForo throws an unhandled XF\Db\DuplicateKeyException (MySQL error 1062) instead of returning a user-friendly validation error.The registration form accepts the input, passes validation, and only fails at the
INSERT stage, resulting in a logged server error visible to admins and a broken experience for the end user.Steps to reproduce:
- Have an existing account with username X already registered.
- Begin OAuth registration via a connected account provider GitHub.
- On the registration completion form (
/register/connected-accounts/github/register), manually enter username X (the conflicting one). - Click the submit button.
Expected behaviour:
A validation error is returned ("That username is already taken."), and the user remains on the registration form.Actual behaviour:
The form submission proceeds past validation, attempts theINSERT INTO xf_user, and throws:
Code:
XF\Db\DuplicateKeyException: MySQL query error [1062]: Duplicate entry 'X' for key 'username'
src/XF/Db/AbstractStatement.php:225
Relevant stack trace:
Code:
#4 src/XF/Mvc/Entity/Entity.php(1578): XF\Db\AbstractAdapter->insert('xf_user', ...)
#5 src/XF/Mvc/Entity/Entity.php(1306): XF\Mvc\Entity\Entity->_saveToSource()
#6 src/XF/Service/User/RegistrationService.php(325): XF\Mvc\Entity\Entity->save()
#7 src/XF/Service/ValidateAndSavableTrait.php(42): XF\Service\User\RegistrationService->_save()
#8 src/XF/Pub/Controller/RegisterController.php(345): XF\Service\User\RegistrationService->save()
#9 src/XF/Mvc/Dispatcher.php(362): XF\Pub\Controller\RegisterController->actionConnectedAccountRegister(...)
Root cause (suspected):
The connected account registration path (actionConnectedAccountRegister) either:- Does not run the same username uniqueness check that the standard registration flow performs, or
- Is susceptible to a TOCTOU race between validation and the actual
INSERT.
RegistrationService::_save() does not catch \XF\Db\DuplicateKeyException and convert it into a user-facing validation error, which it should.Environment:
- Connected account provider: GitHub
- Triggered route:
/register/connected-accounts/github/register - Error class:
XF\Db\DuplicateKeyException - MySQL error: 1062 Duplicate entry for key
username
Fix:RegistrationService::_save() (or the ValidateAndSavableTrait) should catch \XF\Db\DuplicateKeyException on the username key and surface it as a proper validation error. Alternatively, the connected account registration flow should explicitly re-validate username uniqueness immediately before calling save().
