0

I have a problem with trying to login using the saved hash from my database, I save my password the following way, which works fine:

adduser($conn, '3', $username, $password);

This calls the following function:

  function adduser ($conn, $level, $username, $password)
  {
  $password = mysqli_real_escape_string($conn, $password);
  $password = mysqli_real_escape_string($conn, $username);
  $password = password_hash($password, PASSWORD_BCRYPT);
  $user = "INSERT INTO users (level, username, password)
  VALUES ('$level', '$username', '$password')";
  mysqli_query($conn, $user) or die (mysqli_error($conn));
  }

My password field is a CHAR(60) so the stored password hash should be the right size.

When I try to login I call this function:

if (login($conn, $username, $password) === true){

}

Which exists here:

  function login ($conn, $username, $password)
  {
$password = mysqli_real_escape_string($conn, $password);
$username = mysqli_real_escape_string($conn, $username);
$query = "SELECT password FROM `users` WHERE username='$username'";
$result = mysqli_query($conn, $query) or die(mysqli_error($conn));
$row = mysqli_fetch_array($result, MYSQLI_ASSOC);
$hash = $row["password"];
$verify = password_verify($password, $hash);
if ($verify)
  {
    return true;
  }
  else
  {
    return false;
  }
  }

My issue is that it never returns true or false, which makes it impossible for me to login...

Extra: It succesfully post to database

I also tried running this, which succesfully posted the data from my database

$query = "SELECT password FROM `users` WHERE username='$username'";
$result = mysqli_query($conn, $query) or die(mysqli_error($conn));
$row = mysqli_fetch_array($result, MYSQLI_ASSOC);
echo $row["password"]; 

Update


Doing this:

echo '<br/>';
echo $hash;
echo '<br/>';
echo $password;

Gives me the following output:

$2y$10$OfJhVve4GMZRfjfelb8sNOJ7EN5NAAGOmsN6OS/SC7PZGU5mDNOou
hej

Which matches the password in my database

$2y$10$OfJhVve4GMZRfjfelb8sNOJ7EN5NAAGOmsN6OS/SC7PZGU5mDNOou

1 Answers1

2

After testing your entire code, I have come to the following conclusion.

The problem here is that you are escaping the password while inserting it into your database, which is something I did raise in comments from the beginning.

"side note: you shouldn't escape a password/hash function, passwords such as 123'\abc< are perfectly valid and will be modified on insertion."

$password = mysqli_real_escape_string($conn, $username);

Side note for ^ - Consult Edit #2 below, near "However...":

Simply don't use it, just keep/use the assignment normally.

Both password_hash() and password_verify() do their job, so there's no need to escape passwords.

You will need to remove it from the code that you used to insert it into the database with, and start over again with a new set of hashes.

That escaping function is most likely adding a character during insertion.

Side note: Just for the record, my password column is VARCHAR, yet that shoulnd't be a difference from your CHAR (Edit: consult footnote). If it is then ALTER your column to be VARCHAR.

The manual on password_hash() though, suggests using 255 for a length, being a good bet.


Edit footnote:

As per a comment I posted beneath my answer.

It looks to have a difference. This Q&A What's the difference between VARCHAR and CHAR? shows it, as per the accepted answer

VARCHAR is variable-length.

CHAR is fixed length.


Edit #2:

After further testing to see if it made a difference by ALTER'ing the password column from VARCHAR(255) to CHAR(60) made a difference; it did not.

Tests performed:

  • Inserted a new hash without the escaping function and verifying: TRUE.
  • Inserted a new hash with the escaping function and verifying: FALSE.

Therefore and as I stated originally; the fault lies with the use of mysqli_real_escape_string().

However and going over your code again, this line:

$password = mysqli_real_escape_string($conn, $username);

You were using the $username variable here which also accounts for the wrong value being inserted in the database. All of these put together were the problems from the get go.

Community
  • 1
  • 1
Funk Forty Niner
  • 74,450
  • 15
  • 68
  • 141
  • This might aswell be a solution, though I figured changing the length to 72 in the password field, also did the trick without removing the escapes. But thank you for pointing out how it works, I'll make sure to remove it – guitarherokk Apr 28 '17 at 13:11
  • 1
    @guitarherokk Even if you increase the lengh; the initial problem is still there and you need to start over by clearing all your hashes and create new ones. This was the case for me; when I escaped the password, it rendered as FALSE. Removing it rendered it as TRUE. – Funk Forty Niner Apr 28 '17 at 13:12
  • Thank you really appreciate with you and next time i will take care about it – Ahmed Ginani Apr 28 '17 at 13:12
  • Indeed, not sure if the difference is in the VARCHAR and CHAR, perhaps that has to do with it too? Already cleared the hashes, and removed the escapes. But I was able to make it render as TRUE while using the escapes – guitarherokk Apr 28 '17 at 13:13
  • @guitarherokk It looks to have a difference. This Q&A http://stackoverflow.com/q/1885630/1415724 shows it, as per the accepted answer *"VARCHAR is variable-length. CHAR is fixed length."* http://stackoverflow.com/a/1885635/1415724 – Funk Forty Niner Apr 28 '17 at 13:15
  • @guitarherokk *"but I was able to make it render as TRUE while using the escapes"* - Again; don't escape passwords. If and when someone later on decides to use apostrophes or other characters that an escaping function will interpret as being a possible SQL injection, the login will fail on `password_verify()` since and for example: `123'hello` will be technically be modified/inserted as `123\'abc` in and embedded in the hash; don't do that. – Funk Forty Niner Apr 28 '17 at 13:20
  • can the downvoter please explain their downvote? I would like to know and if I made an error or a misconception about something so I can fix it. – Funk Forty Niner Apr 28 '17 at 13:21
  • @guitarherokk I made a few more edits to my answer and I would like you to reload it and see them further below from my original post. There were a few things happening in there that you were not aware of, including myself till I went over your code again. – Funk Forty Niner Apr 28 '17 at 14:37
  • 1
    @Bsienn I felt that I had to further test this and to improve my answer in order to show the OP and future visitors what was going on in there. *Cheers* – Funk Forty Niner Apr 28 '17 at 14:42