-3

I am having problems verifying a password stored in a mySQL database using password_hash. The insert query takes values from a form

query = "INSERT INTO users (email, password, diary) VALUES ('"
        .mysqli_real_escape_string($link, $_POST['email'])."', '"
        .password_hash(mysqli_real_escape_string($link, $_POST['password']), PASSWORD_DEFAULT)."', '"
        .mysqli_real_escape_string($link, $_POST['password'])."')";

When I try to verify it using

if(password_verify(mysqli_real_escape_string($link, $_POST['password'], $row['password']))) {

it always comes out as invalid password, even though I know I am entering it correctly.

Can anyone help please?

Jens
  • 67,715
  • 15
  • 98
  • 113
Nik
  • 5
  • 3
  • 2
    Do not escape the Password before hashing it – Jens Apr 27 '17 at 10:23
  • 1
    You escape the string: `$_POST['password'], $row['password']` in `if!`!! but you want `$_POST['password']#` – Jens Apr 27 '17 at 10:24
  • Why do you store the password twice? (First one is hashed, second one is plain-text) – Tom Udding Apr 27 '17 at 10:25
  • Your script is at risk of [SQL Injection Attack](http://stackoverflow.com/questions/60174/how-can-i-prevent-sql-injection-in-php) Have a look at what happened to [Little Bobby Tables](http://bobby-tables.com/) Even [if you are escaping inputs, its not safe!](http://stackoverflow.com/questions/5741187/sql-injection-that-gets-around-mysql-real-escape-string) Use [prepared parameterized statements](http://php.net/manual/en/mysqli.quickstart.prepared-statements.php) – RiggsFolly Apr 27 '17 at 10:25
  • And your close brackets are a total disaster in the `password_verify()` attempt anyway – RiggsFolly Apr 27 '17 at 10:27
  • Add `ini_set('display_errors', 1); ini_set('log_errors',1); error_reporting(E_ALL); mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);` to the top of your script. This will force any `mysqli_` errors to generate an Exception that you can see on the browser and other errors will also be visible on your browser. – RiggsFolly Apr 27 '17 at 10:27
  • I store it twice as a test - so I know what the hashed password is based on That will not be in the final version! – Nik Apr 27 '17 at 10:45

1 Answers1

-2

It appears that you have made some mistakes with the parentheses in your if-statement.

What you have is this:

if (password_verify(
        mysqli_real_escape_string(
            $link, 
            $_POST['password'], 
            $row['password']
         )
     )
) {

What happens is that you escape not only $_POST['password'] but also $row['password'] because your parentheses are placed incorrectly, while it should be:

if (password_verify(
        mysqli_real_escape_string(
            $link, 
            $_POST['password']
        ), 
        $row['password']
    )
) {


As Jens mentioned, you should not escape the password before hashing it. This answer has some in-depth information about why you should not escape your passwords before hashing.

And as RiggsFolly mentioned, your SQL query is still vulnerable to SQL injections, even if you escape the input.

Community
  • 1
  • 1
Tom Udding
  • 2,264
  • 3
  • 20
  • 30
  • Please read the first comment under the question from @Jens. Escaping the password runs the risk of changing it, Why would you do that? – RiggsFolly Apr 27 '17 at 10:31