0

以下是在单击表单的更改密码按钮时运行的脚本。该表单包含 2 个密码字段,一个用于新密码,一个用于确认新密码。这是表单的操作脚本:

<?php
session_start();

include("func.php");

$NewPassword = mysql_real_escape_string(md5($_POST['newpassword']));
$Confirm = mysql_real_escape_string(md5($_POST['confirmnewpassword']));
$userid = $_SESSION['username'];

if (!isset($NewPassword) || !isset($Confirm)) {
    header("Location: ../error.php");
    die("Error");
}else if ($NewPassword <> $Confirm) {
    header("Location: ../error.php");
    die("Error");
}else{
    dbConnect();

    mysql_query("UPDATE users SET password='$Confirm' WHERE username='$userid'");

    mysql_close($connect);

    header("Location: ../profile.php");
    die("Success");
}
?>

即使表单上的 2 个密码字段为空或不匹配,密码仍会在数据库中更新。这可能是什么原因?

我感谢提供的任何帮助。

4

3 回答 3

1

您不需要包含 md5 函数的 mysql_real_escape_string,因为 md5 返回一个十六进制数。

 if (!isset($NewPassword) || !isset($Confirm)) {

永远不会评估为真,您应该检查 $_POST['newpassword'] 和 $_POST['confirmnewpassword'] 是否不为空 - 在这种情况下,如果密码都为空,则密码将被更新。

关于即使密码不同也会更新密码,您是否 100% 确定您使用 POST 而不是 GET 传递变量,并且参数的名称是“newpassword”和“confirmnewpassword”?

试着放一个“回声”来显示变量的值,以确保你正确地传递了参数,99% 的问题就在那里。

于 2012-11-03T18:51:27.060 回答
1

您的代码中没有任何内容可以防止空字符串被散列和上传。您正在检查哈希,而不是原始字符串。这可以解释为什么空值仍然得到更新。

但是,如果值不匹配,它们的哈希值应该不同。这将向我表明这可能是您的变量$_POST['newpassword']并且$_POST['confirmnewpassword']不准确。正如其他人所建议的那样,代码开头的var_dump甚至print_r($_POST)语句将帮助您诊断这一点。

甚至不涉及诸如 PDO 与 mysql 之类的大问题或以不同的方式构建代码,这就是我要做的:

session_start();
include("func.php");

print_r ($_POST); // you'll want to delete this later 

$new_password = $_POST['newpassword']; // not technically necessary, my preferred style
$confirm_password = $_POST['confirmnewpassword']; // also not technically necessary
$userid = $_SESSION['username'];


/* Test the actual submitted password and confirmation to ensure they are set */
if (empty ($new_password) || empty ($confirm_password)) {
    /* header("Location: ../error.php"); */ // comment this out for now
    die ("Error: Password or Password Confirmation not set");
}

/* Test the actual submitted password and confirmation to ensure they match */
elseif ($new_password != $confirm_password) {
    /* header("Location: ../error.php"); */ // comment this out for now
    die("Error: Password and Password Confirmation do not match");
}

else {
    /* NOW that you have established the password and confirmation are both
     * set AND match, you get the hash value */
    $password_hash = mysql_real_escape_string(md5($new_password));
    dbConnect(); 
    mysql_query("UPDATE users SET password='$Confirm' WHERE username='$userid'");
    mysql_close($connect);
    /* header("Location: ../profile.php"); */ // comment this out for now
    die("Success: Updated");
}

这应该允许您调试脚本并查看发生了什么问题。我的猜测是数据要么作为 GET 传递,要么变量名不正确。

下一步:

  1. 工作后,删除 var_dump 并取消注释您的重定向。
  2. 考虑重新编写 if 语句,以更明确地测试密码是否正确,如其他答案之一所述。
  3. 说真的,看看PDOmysqli。程序 mysql_* 正在被贬低。
  4. 如果您不想走完整的 OOP 路线,请考虑制作 update_password () 和 send_error () 之类的函数。这将使您的代码更具可读性和可重用性。

但是一步一步,让我们调试这些当前的东西!

于 2012-11-03T20:12:17.500 回答
0

我找不到这不起作用的具体原因(尝试使用调试器或调试消息),但我肯定不会将我的密码更新放在“其他”分支中!仅当您 100% 确定新密码及其确认匹配并且它们已根据您的密码策略进行验证时才更新密码。至少确保它们不是空字符串。

于 2012-11-03T18:55:26.820 回答