From e1b87303c101f54ab560646802c56e954c3f3498 Mon Sep 17 00:00:00 2001 From: Kestas Kuliukas Date: Fri, 23 Jul 2021 20:23:09 +0800 Subject: [PATCH] Minor security patches --- lib/auth.php | 37 +++++++++++++++++++++++++++++++++++++ locales/English/user.php | 5 +++-- logon.php | 8 ++++++++ usercp.php | 4 ++++ 4 files changed, 52 insertions(+), 2 deletions(-) diff --git a/lib/auth.php b/lib/auth.php index abf35ac6e..e3fd937e0 100755 --- a/lib/auth.php +++ b/lib/auth.php @@ -104,6 +104,43 @@ public static function gamemasterToken($gameID) return $gameID.'_'.$time.'_'.self::gamemasterToken_Key($gameID,$time); } + // Functions which can be used to prove that a form being submitted was generated by the server, and not + // by an attacker who might trick a user into loading a page that submits malicious data to a webDiplomacy form + // and have it successfully submit from that user. Reported by @ranjit-git + // Checks $_REQUEST['formToken'] + public static function formToken_Valid() + { + if( !isset($_REQUEST['formToken']) + { + throw new Exception(l_t('No form token provided; form cannot be processed.')); + } + $formToken = $_REQUEST['formToken']; + $token = explode('_',$formToken); + if( count($token) != 2 ) + throw new Exception(l_t('Corrupt form token %s',$formToken)); + + list($time, $hash) = $token; + if ( self::formToken_Key($time) != $hash ) + throw new Exception(l_t('Invalid form token %s',$formToken)); + + if ( (time()-$time)>60*60 ) + throw new Exception(l_t('Form token %s expired (%s), over an hour old. Please resubmit.',$formToken,time())); + } + private static function formToken_Key($time) + { + return md5($time.Config::$secret); + } + private static $formToken_cached = false; + public static function formTokenHTML() + { + if( $formToken_cached === false ) + { + $time=time(); + $formToken_cached = ''; + } + return $formToken_cached; // One token per page is fine + } + /** * Return a URL allowing the user to validate a given e-mail. * emailToken is the name used, and additional GET vars can be added diff --git a/locales/English/user.php b/locales/English/user.php index b94dd290b..e6a84f5f4 100755 --- a/locales/English/user.php +++ b/locales/English/user.php @@ -170,8 +170,9 @@ */ print ' -

- +

'; +print libAuth::formTokenHTML(); +print ' '; ?> diff --git a/logon.php b/logon.php index 71a2860b0..adb5f1844 100755 --- a/logon.php +++ b/logon.php @@ -58,6 +58,14 @@ "go back and check your spelling.")); } + if( $MC->get('forgot_'+$forgottenUser->id) !== false ) + { + throw new Exception(l_t("To help prevent abuse please wait 5 minutes before resending forgotten e-mail recovery links. ". + "In the meantime please check your spam folder for a missing recovery e-mail, or contact the moderator team.")); + } + + $MC->set('forgot_'+$forgottenUser->id, 5*60); // Set a flag preventing resends for 5 minutes + require_once(l_r('objects/mailer.php')); $Mailer = new Mailer(); $Mailer->Send(array($forgottenUser->email=>$forgottenUser->username), l_t('webDiplomacy forgotten password verification link'), diff --git a/usercp.php b/usercp.php index 97b46adef..36fcb9c0e 100755 --- a/usercp.php +++ b/usercp.php @@ -39,6 +39,8 @@ if ( isset($_REQUEST['emailToken'])) { + libAuth::formToken_Valid(); + if( !($email = libAuth::emailToken_email($_REQUEST['emailToken'])) ) libHTML::notice(l_t("Email change validation"), l_t("A bad email token was given, please check the validation link try again")); @@ -56,6 +58,8 @@ if ( isset($_REQUEST['userForm']) ) { + libAuth::formToken_Valid(); + $formOutput = ''; try