From 5f005e1d5607649dc7ad021e73ec89986f1789dc Mon Sep 17 00:00:00 2001 From: novgorodschi catalin Date: Fri, 3 Jul 2026 10:07:38 +0300 Subject: [PATCH] Fix forgotten password vulnerability Fix forgotten password vulnerability --- password.php | 209 ++++++++++++++++++++++++++++++++------------------- 1 file changed, 132 insertions(+), 77 deletions(-) diff --git a/password.php b/password.php index f959b005..1f505dff 100644 --- a/password.php +++ b/password.php @@ -3,10 +3,10 @@ ################################################################################# ## -= YOU MAY NOT REMOVE OR CHANGE THIS NOTICE =- ## ## --------------------------------------------------------------------------- ## -## Filename : password.php ## +## Filename : password.php ## ## Type : In Game Password Page ## ## --------------------------------------------------------------------------- ## -## Developed by : Dzoki ## +## Developed by : Dzoki ## ## Refactored by : Shadow ## ## Redesign by : Shadow ## ## --------------------------------------------------------------------------- ## @@ -22,118 +22,173 @@ use App\Utils\AccessLogger; -if(!file_exists('var/installed') && @opendir('install')) { - header("Location: install/"); - exit; +if (!file_exists('var/installed') && @opendir('install')) { + header("Location: install/"); + exit; } + include_once("GameEngine/config.php"); include_once("GameEngine/Lang/" . LANG . ".php"); include_once("GameEngine/Database.php"); include_once("GameEngine/Mailer.php"); include_once("GameEngine/Generator.php"); + AccessLogger::logRequest(); -if(!isset($_REQUEST['npw'])){ - header("Location: login.php"); - exit; +if (!isset($_REQUEST['npw'])) { + header("Location: login.php"); + exit; } ?> - + - - <?php echo SERVER_NAME; ?> - Forgotten Password - - - - - - - - - - - - - - + + <?php echo SERVER_NAME; ?> - Forgotten Password + + + + + + + + + + + + + + + +
-
-
+
+
+ -
-

new password

-
forgotten password
+
+ +

new password

+
forgotten password
getUserField($uid, 'email', 0); - $username = $database->getUserField($uid, 'username', 0); - if($email != $_POST['email']){ - echo "

Unfortunately the entered email address does not match the one used to register the account.

\n"; - }else{ - // generate password and cpw - $npw = $generator->generateRandStr(7); - $cpw = $generator->generateRandStr(10); - $database->addPassword($uid, $npw, $cpw); +// User submitted email address +if (isset($_POST['email']) && isset($_POST['npw'])) { - // send password mail - $mailer->sendPassword($email, $uid, $username, $npw, $cpw); + $uid = (int)$_POST['npw']; + $submittedEmail = trim($_POST['email']); - echo "

Password was sent to: ${_POST['email']}

\n"; - } + // Mesaj generic pentru a evita user enumeration + $genericMessage = + '

If the account information is valid, a password reset email has been sent.

'; - // user click the link in 'password forgotten' email - }else if(isset($_GET['cpw']) && isset($_GET['npw'])){ - $uid = intval($_GET['npw']); - $cpw = preg_replace('#[^a-zA-Z0-9]#', '', $_GET['cpw']); + if ($uid <= 0 || $submittedEmail === '') { - if(!$database->resetPassword($uid, $cpw)){ - echo '

The password has not been changed. Perhaps the activation code has already been used.

'; - }else{ - echo '

The password has been successfully changed.

'; - } + echo $genericMessage; + } else { - // user click 'generate password' link in login fail page, display input form here - }else { + $email = $database->getUserField($uid, 'email', 0); + $username = $database->getUserField($uid, 'username', 0); + // Verifică dacă utilizatorul există și emailul corespunde + if ( + !is_string($email) || + $email === '' || + !is_string($username) || + $username === '' || + !hash_equals($email, $submittedEmail) + ) { + + echo $genericMessage; + + } else { + + // Generate password and confirmation code + $npw = $generator->generateRandStr(7); + $cpw = $generator->generateRandStr(10); + + $database->addPassword($uid, $npw, $cpw); + + // Send password email + $mailer->sendPassword($email, $uid, $username, $npw, $cpw); + + // Escape output to prevent XSS + echo '

Password was sent to: ' . + htmlspecialchars($submittedEmail, ENT_QUOTES, 'UTF-8') . + '

'; + } + } + +// User clicked confirmation link from email +} elseif (isset($_GET['cpw']) && isset($_GET['npw'])) { + + $uid = (int)$_GET['npw']; + $cpw = preg_replace('#[^a-zA-Z0-9]#', '', $_GET['cpw']); + + if (!$database->resetPassword($uid, $cpw)) { + echo '

The password has not been changed. Perhaps the activation code has already been used.

'; + } else { + echo '

The password has been successfully changed.

'; + } + +// Display form +} else { ?> -

Before you can request a new password you have to enter the email address that has been used to register the account. -

Afterwards you will receive an e-mail with a new password. The password will only work after confirming it, though.

-
-

- Email
- - -

-

- -

-
- -
-
+

+ Before you can request a new password you have to enter the email + address that has been used to register the account. +

+ Afterwards you will receive an e-mail with a new password. + The password will only work after confirming it, though. +

+ +
+

+ Email
+ + +

+ +

+ +

+
+ + +
+
+
-
+
- -
+ +
+
+