0

I can't get this to work. I am new to working with prepared statements so i i'm kinda 50/50 on what i'm doing.

Upon registration, the password is hashed with password_hash($pass,PASSWORD_DEFAULT)

Now, i'm trying to get my login page to function with this but i dont know where / how to write it with the password_verify()

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

        $sql = "SELECT * FROM users WHERE BINARY username=? AND password=?";
            $stmt = $db->prepare($sql);
                $stmt->bind_param("ss",$username,$password);
                $stmt->execute();
                $result = $stmt->get_result();
                $num_rows = $result->num_rows;

                if($num_rows == 1){

                    $rows = $result->fetch_assoc();
                    if(password_verify($password, $rows['password'])){
                    $_SESSION['loggedin'] = $username;
                    $_SESSION['country'] = $rows['country'];
                    $_SESSION['email'] = $rows['email'];
                    $_SESSION['avatar'] = $rows['u_avatar'];
                    $_SESSION['is_gm'] = $rows['is_gm'];
                    $_SESSION['user_lvl'] = $rows['user_lvl'];
                    $_SESSION['totalposts'] = $rows['post_total'];
                    $_SESSION['totalcoins'] = $rows['coins_total'];
                    $_SESSION['totalvotes'] = $rows['vote_total'];
                    $_SESSION['secquest'] = $rows['sec_quest'];
                    $_SESSION['secanswer'] = $rows['sec_answer'];
                    $_SESSION['join_date'] = $rows['join_date'];

                    header("Location: /index.php");
                    exit();
                    }
                } else {
                    echo "<p class='error_msg'>No accounts could be found with the given credentials.</p>";
                }

                $stmt->free_result();
                $stmt->close();
                $db->close();

I would assume that the password verify would before if($num_rows == 1) but as i said, i have no idea.

Synyster
  • 41
  • 5
  • You can't select the password from the database like that. In the select statement, you're trying to compare the plain text password to the hash. – Devon Bessemer Sep 30 '16 at 16:15
  • Seeing your other question http://stackoverflow.com/q/39781691/ where you were using md5 to store password hashes, I am betting that your password column isn't long enough. If it's anything <60, it is silently failing here. If so, you have to start over again with new saved hashes. I am (fairly) confident about this "answer". What is the value of a saved hash btw and length including the password column's length? – Funk Forty Niner Sep 30 '16 at 16:16
  • I already took the opportunity after my previous question was answered and changed the length to 150 so it can't be that. @Fred-ii- – Synyster Sep 30 '16 at 16:19
  • *Hm....*, well what I don't understand is; if the other question was solved, why is this one failing all of a sudden? Something isn't right. – Funk Forty Niner Sep 30 '16 at 16:20
  • I would remove the BINARY from this `WHERE BINARY username=? AND password=?` - try that and see. Or select only the password. – Funk Forty Niner Sep 30 '16 at 16:22
  • @Fred-ii-, he is binding the plain text password in the statement. – Devon Bessemer Sep 30 '16 at 16:22
  • Use this http://stackoverflow.com/a/27482611/ you need to bind the result(s), then fetch. – Funk Forty Niner Sep 30 '16 at 16:26
  • @Devon Yeah you're right; I noticed that which is why I edited my comment above in adding *"Or select only the password."*. – Funk Forty Niner Sep 30 '16 at 16:39
  • Sure like to know the status of your question here. Devon's provided you with an answer and I a link. @Synyster – Funk Forty Niner Sep 30 '16 at 16:47

1 Answers1

1

Your query is essentially:

SELECT * FROM users WHERE username=username AND password_hash=plain_text_password

This isn't going to work. If you're relying on PHP password hashing, you can't do a password comparison on the SQL level. Retrieve the password hash from the database then do the password_verify (exclude the password=?) in your WHERE arguments.

Devon Bessemer
  • 34,461
  • 9
  • 69
  • 95