-1

I am having some issues with using password_hash and password_verify, I have the code below, and by my eyes should work perfectly. But password_verify always returns false when the user logs on. Any help would be appreciated;

Password Register Script

$passVerifyString = $_GET["verify"];

$resetPasswordOne = $_POST['inputPasswordOne'];
$resetPasswordTwo = $_POST['inputPasswordTwo'];

if($resetPasswordOne != $resetPasswordTwo){
    $resetError = "The passwords do not match";
}
else {
    if (isset($_POST['submit'])) {
        $updatedPass = password_hash($resetPasswordOne, PASSWORD_DEFAULT);
        $passUpdateSql = "UPDATE companyUsers SET userPass='$updatedPass', passVerify='' WHERE passVerify='$passVerifyString'";

    if (mysqli_query($db, $passUpdateSql)) {
        $resetError = "Your password has been sucessfully reset";
    } 
    }

}

User Logon Script (reduced version)

    $username=$_POST['username'];
    $password=$_POST['password'];

    // To protect MySQL injection for Security purpose
    $username = stripslashes($username);
    $password = stripslashes($password);

    // SQL query to fetch information of registered users and finds user match.

    $logon_sql = mysqli_query($db,"SELECT userId, userPass FROM companyUsers WHERE userLogin='$username'");

    $row = mysqli_fetch_array($logon_sql,MYSQLI_ASSOC);

    $userId = $row['userId'];
    $hash = $row['userPass'];

    $_SESSION['userId']=$userId;

    if(empty($userId)){
        $error = "Incorrect Username";
    }
    else{

    if (password_verify($password, $hash)) {
        $error= "Verified, Logging In";
        header("location: https://XXXXXXXXXXXXXXXX/home.php");
    }
    else {
        $error = "Incorrect Password";
    }

Thanks all, I know this code doesn't follow the greatest security protocol, this is just the testing version before I protect it.

Ash Taylor
  • 19
  • 3
  • 1
    stripslashes changes the password, obviously, and does nothing to prevent SQL injection. stripslashes is never necessary in correct code. Use [parameterized statements](https://www.php.net/manual/en/mysqli.quickstart.prepared-statements.php), always. – Peter May 08 '20 at 05:03
  • Thanks for that, I had those left in from some early testing, my mistake! Unfortunately still no change to my situation. – Ash Taylor May 08 '20 at 05:17
  • 1
    Check the length of the column storing the password hash and make sure it is atleast varchar(60) – Rotimi May 08 '20 at 05:34
  • @AshTaylor Your code is vulnerable to SQL injection. Please fix this. https://stackoverflow.com/questions/60174/how-can-i-prevent-sql-injection-in-php – Michas May 08 '20 at 10:14

2 Answers2

1

Based on the documentation, can you please ensure that password column has minimum varchar(60).

PASSWORD_DEFAULT - Use the bcrypt algorithm (default as of PHP 5.5.0). Note that this constant is designed to change over time as new and stronger algorithms are added to PHP. For that reason, the length of the result from using this identifier can change over time. Therefore, it is recommended to store the result in a database column that can expand beyond 60 characters (255 characters would be a good choice).

Additionally, can you just try to do another hash on password and see if you can compare that with the value stored in DB. PS: this is only for testing.

So something like

if(password_hash($password, PASSWORD_DEFAULT) == $hash) {
   echo "pass";
}
else{
   echo "hash  $hash,  password_hash($password, PASSWORD_DEFAULT)" ;
}

I understand this is not required, but asking you to test just to confirm what values you are getting from DB vs password_hash(). Since verify is using the same function.

Shubham Singh
  • 946
  • 6
  • 12
-1

Your SQL statement is not seeing the variables you having included as variables. Try this:

  $passUpdateSql = "UPDATE companyUsers 
                    SET userPass=".$updatedPass.", passVerify='' 
                    WHERE passVerify=".$passVerifyString;

As you mention though, this way of using SQL is not secure and is vulnerables to attacks. You should use binding instead.

fraggley
  • 1,215
  • 2
  • 9
  • 19
  • When I look in the database the row is being updated with my current code, and works the same way with the same result with or without ".$variable." – Ash Taylor May 08 '20 at 04:49
  • You need to debug it to make sure the correct information is being pulled from the database with var_dump($row); exit(); Make sure that $userId and $hash are correctly populated before running password_verify(); – fraggley May 08 '20 at 05:02
  • They certainly are, ran with var_dump, and got exactly the right information back. – Ash Taylor May 08 '20 at 05:18
  • Can I ask - how do you know it's not verifying? Are you sure your header() call is just not throwing out an error? What does your console say? I would remove header() and have your true and false statements as echo 'working'; and echo 'failed"; so you can clearly see if the password_verify function is working – fraggley May 08 '20 at 05:29