Require current password when setting a new one

Message ID 20200130093426.5174-1-lfleischer@archlinux.org
State New
Headers show
Series Require current password when setting a new one | expand

Commit Message

Lukas Fleischer Jan. 30, 2020, 9:34 a.m. UTC
Prevent from easily taking over an account by changing the password with
a stolen session ID.

Fixes FS#65325.

Signed-off-by: Lukas Fleischer <lfleischer@archlinux.org>
---
 web/html/account.php               |  1 +
 web/html/register.php              |  2 ++
 web/lib/acctfuncs.inc.php          | 15 ++++++++++++--
 web/template/account_edit_form.php | 32 +++++++++++++++++++-----------
 4 files changed, 36 insertions(+), 14 deletions(-)

Patch

diff --git a/web/html/account.php b/web/html/account.php
index 1d59e9c..7c6c424 100644
--- a/web/html/account.php
+++ b/web/html/account.php
@@ -34,6 +34,7 @@  if ($action == "UpdateAccount") {
 			in_request("S"),
 			in_request("E"),
 			in_request("H"),
+			in_request("PO"),
 			in_request("P"),
 			in_request("C"),
 			in_request("R"),
diff --git a/web/html/register.php b/web/html/register.php
index a426482..8174e34 100644
--- a/web/html/register.php
+++ b/web/html/register.php
@@ -26,6 +26,7 @@  if (in_request("Action") == "NewAccount") {
 		in_request("H"),
 		'',
 		'',
+		'',
 		in_request("R"),
 		in_request("L"),
 		in_request("TZ"),
@@ -54,6 +55,7 @@  if (in_request("Action") == "NewAccount") {
 			in_request("H"),
 			'',
 			'',
+			'',
 			in_request("R"),
 			in_request("L"),
 			in_request("TZ"),
diff --git a/web/lib/acctfuncs.inc.php b/web/lib/acctfuncs.inc.php
index e754989..1de49b0 100644
--- a/web/lib/acctfuncs.inc.php
+++ b/web/lib/acctfuncs.inc.php
@@ -96,6 +96,7 @@  function display_account_form($A,$U="",$T="",$S="",$E="",$H="",$P="",$C="",$R=""
  * @param string $S Whether or not the account is suspended
  * @param string $E The e-mail address for the user
  * @param string $H Whether or not the e-mail address should be hidden
+ * @param string $PO The old password of the user
  * @param string $P The password for the user
  * @param string $C The confirmed password for the user
  * @param string $R The real name of the user
@@ -116,7 +117,7 @@  function display_account_form($A,$U="",$T="",$S="",$E="",$H="",$P="",$C="",$R=""
  *
  * @return array Boolean indicating success and message to be printed
  */
-function process_account_form($TYPE,$A,$U="",$T="",$S="",$E="",$H="",$P="",$C="",
+function process_account_form($TYPE,$A,$U="",$T="",$S="",$E="",$H="",$PO="",$P="",$C="",
 		$R="",$L="",$TZ="",$HP="",$I="",$K="",$PK="",$J="",$CN="",$UN="",$ON="",$UID=0,$N="",$captcha_salt="",$captcha="") {
 	global $SUPPORTED_LANGS;
 
@@ -134,6 +135,7 @@  function process_account_form($TYPE,$A,$U="",$T="",$S="",$E="",$H="",$P="",$C=""
 
 	if(isset($_COOKIE['AURSID'])) {
 		$editor_user = uid_from_sid($_COOKIE['AURSID']);
+	$row = account_details(in_request("ID"), in_request("U"));
 	}
 	else {
 		$editor_user = null;
@@ -159,9 +161,18 @@  function process_account_form($TYPE,$A,$U="",$T="",$S="",$E="",$H="",$P="",$C=""
 			. "</li>\n</ul>";
 	}
 
-	if (!$error && $P && $C && ($P != $C)) {
+	if (!$error && $P && !$C) {
+		$error = __("Please confirm your new password.");
+	}
+	if (!$error && $P && !$PO) {
+		$error = __("Please enter your old password in order to set a new one.");
+	}
+	if (!$error && $P && $P != $C) {
 		$error = __("Password fields do not match.");
 	}
+	if (!$error && $P && check_passwd($UID, $PO) != 1) {
+		$error = __("The old password is invalid.");
+	}
 	if (!$error && $P != '' && !good_passwd($P)) {
 		$length_min = config_get_int('options', 'passwd_min_len');
 		$error = __("Your password must be at least %s characters.",
diff --git a/web/template/account_edit_form.php b/web/template/account_edit_form.php
index 5e84aa7..25e9185 100644
--- a/web/template/account_edit_form.php
+++ b/web/template/account_edit_form.php
@@ -86,18 +86,6 @@ 
 			<input type="checkbox" name="H" id="id_hide" <?= $H ? 'checked="checked"' : '' ?> />
 		</p>
 
-		<?php if ($A == "UpdateAccount"): ?>
-		<p>
-			<label for="id_passwd1"><?= __("Password") ?>:</label>
-			<input type="password" size="30" name="P" id="id_passwd1" value="<?= $P ?>" />
-		</p>
-
-		<p>
-			<label for="id_passwd2"><?= __("Re-type password") ?>:</label>
-			<input type="password" size="30" name="C" id="id_passwd2" value="<?= $C ?>" />
-		</p>
-		<?php endif; ?>
-
 		<p>
 			<label for="id_realname"><?= __("Real Name") ?>:</label>
 			<input type="text" size="30" maxlength="32" name="R" id="id_realname" value="<?= htmlspecialchars($R,ENT_QUOTES) ?>" />
@@ -150,6 +138,26 @@ 
 		</p>
 	</fieldset>
 
+	<?php if ($A == "UpdateAccount"): ?>
+	<fieldset>
+		<legend><?= __("If you want to change your password, enter your current passport, your new password and confirm the new password by entering it again.") ?></legend>
+		<p>
+			<label for="id_passwd_old"><?= __("Old password") ?>:</label>
+			<input type="password" size="30" name="PO" id="id_passwd_old" value="<?= $PO ?>" />
+		</p>
+
+		<p>
+			<label for="id_passwd1"><?= __("Password") ?>:</label>
+			<input type="password" size="30" name="P" id="id_passwd1" value="<?= $P ?>" />
+		</p>
+
+		<p>
+			<label for="id_passwd2"><?= __("Re-type password") ?>:</label>
+			<input type="password" size="30" name="C" id="id_passwd2" value="<?= $C ?>" />
+		</p>
+	</fieldset>
+	<?php endif; ?>
+
 	<fieldset>
 		<legend><?= __("The following information is only required if you want to submit packages to the Arch User Repository.") ?></legend>
 		<p>