From 1f9ca35d7b874a6a3b82a35c7e4eaaff35303dc2 Mon Sep 17 00:00:00 2001 From: Marcel Werk Date: Fri, 2 May 2025 15:10:42 +0200 Subject: [PATCH] Fix race condition in `EmailMultifactorMethod` Closes #6265 --- .../EmailMultifactorMethod.class.php | 32 +++++-------------- 1 file changed, 8 insertions(+), 24 deletions(-) diff --git a/wcfsetup/install/files/lib/system/user/multifactor/EmailMultifactorMethod.class.php b/wcfsetup/install/files/lib/system/user/multifactor/EmailMultifactorMethod.class.php index 46b13fe4bc5..d61055b0d9e 100644 --- a/wcfsetup/install/files/lib/system/user/multifactor/EmailMultifactorMethod.class.php +++ b/wcfsetup/install/files/lib/system/user/multifactor/EmailMultifactorMethod.class.php @@ -238,40 +238,24 @@ public function createAuthenticationForm(IFormDocument $form, Setup $setup): voi */ public function processAuthenticationForm(IFormDocument $form, Setup $setup): void { - $userCode = $form->getData()['data']['code']; - - $sql = "SELECT code - FROM wcf1_user_multifactor_email - WHERE setupID = ? - AND createTime > ? - FOR UPDATE"; - $statement = WCF::getDB()->prepare($sql); - $statement->execute([ + $this->invalidateUsedCode( $setup->getId(), - (\TIME_NOW - self::LIFETIME), - ]); - $codes = $statement->fetchAll(\PDO::FETCH_ASSOC); - - $usedCode = $this->findValidCode($userCode, $codes); - - if ($usedCode === null) { - throw new \RuntimeException('Unable to find a valid code.'); - } + $form->getData()['data']['code'] + ); + } + private function invalidateUsedCode(int $id, string $code): void + { $sql = "DELETE FROM wcf1_user_multifactor_email WHERE setupID = ? AND createTime > ? AND code = ?"; $statement = WCF::getDB()->prepare($sql); $statement->execute([ - $setup->getId(), + $id, (\TIME_NOW - self::LIFETIME), - $usedCode['code'], + $code, ]); - - if ($statement->getAffectedRows() !== 1) { - throw new \RuntimeException('Unable to invalidate the code.'); - } } /**