Wayne Fellows
Wayne Fellows

Reputation: 13

password_verify having a few issues hopefully someone can help me

So im making a login for a game system that uses a JSON string to read back the files, however when I Hash the password and try login it doesn't work however when the password is unhased it works fine, I think the problem lies with the password verify part.

Im just unsure where to place it if someone could guide me in the right direction that will be amazing...

So the issue is when I send the $password example test5 it only reads as test 5 and not this $2y$10$viov5WbMukXsCAfIJUTUZetGrhKE9rXW.mAH5F7m1iYGfxyQzQwD.

This was the original Code

<?php

include("dbconnect.php");


/////// First Function To Get User Data For Login 



if($_GET["stuff"]=="login"){

$mysqli = new mysqli($DB_host, $DB_user, $DB_pass, $DB_name);

    if (mysqli_connect_errno()) {
        printf("Connect failed: %s\n", mysqli_connect_error());
        exit();
    }


/////// Need to Grab Username And Password

$username = $_GET["user"];
$password = $_GET["password"];


$query = "SELECT username, password, regkey, banned FROM users WHERE username='$username' and password='$password'";

if ($stmt = $mysqli->prepare($query)) {
    $stmt->execute();
    $stmt->bind_result($username, $password, $regkey, $banned);
    while ($stmt->fetch()) {
     echo "{";
     echo '"result": "success",';
        echo '"regkey": "' . $regkey . '",';
         echo '"banned": "' . $banned . '"';
        echo "}";
    }

    $stmt->close();
}

$mysqli->close();

}

Then I tried This

<?php

include("dbconnect.php");


/////// First Function To Get User Data For Login 



if($_GET["stuff"]=="login"){

$mysqli = new mysqli($DB_host, $DB_user, $DB_pass, $DB_name);

    if (mysqli_connect_errno()) {
        printf("Connect failed: %s\n", mysqli_connect_error());
        exit();
    }


/////// Need to Grab Username And Password

$username = $_GET["user"];
$password = $_GET["password"];

$GetPassword = "SELECT password FROM users WHERE username='$username'";

$data = mysqli_query($GetPassword);

if(password_verify($password, $data['password'])) {

            $query = "SELECT username, password, regkey, banned FROM users WHERE username='$username' and password='$password'";
            if ($stmt = $mysqli->prepare($query)) {
            $stmt->execute();
            $stmt->bind_result($username, $password, $regkey, $banned);
            while ($stmt->fetch()) {
             echo "{";
             echo '"result": "success",';
                echo '"regkey": "' . $regkey . '",';
                 echo '"banned": "' . $banned . '"';
                echo "}";
            }

            $stmt->close();


        }
} else {
    // password is in-correct
}


$mysqli->close();

}

Upvotes: 1

Views: 239

Answers (2)

Rajdeep Paul
Rajdeep Paul

Reputation: 16963

There are several issues with your code, such as:

  • This statement $data = mysqli_query($GetPassword) is wrong. mysqli_query() expects first argument to be your connection handler, so it should be,

    $data = mysqli_query($mysqli, $GetPassword);
    
  • Look at this statement, if(password_verify($password, $data['password'])) { ... mysqli_query(), on success, returns a result set, so you can't get the password using $data['password']. First fetch the row from the result set and then get the password, like this,

    $row = mysqli_fetch_assoc($data);
    if(password_verify($password, $row['password'])) { ...
    
  • Look at the following query,

    $query = "SELECT username, password, regkey, banned FROM users WHERE username='$username' and password='$password'";
    

    This query won't return any rows because of this WHERE condition, ...password='$password'. So the solution is, instead using two separate queries, use only one query to validate the password and retrieve relevant data. The solution is given down below.

  • Your queries are susceptible to SQL injection. Always prepare, bind and execute your queries to prevent any kind of SQL injection.

  • If you want to build a json string then instead of doing echo "{"; echo '"result": "success",'; ..., create an array comprising of all the relevant data and then json_encode the array.

So the solution would be like this:

// your code

$username = $_GET["user"];
$password = $_GET["password"];

// create a prepared statement
$stmt = mysqli_prepare($mysqli, "SELECT username, password, regkey, banned FROM users WHERE username=?");

// bind parameters
mysqli_stmt_bind_param($stmt, 's', $username);

// execute query
mysqli_stmt_execute($stmt);

// store result
mysqli_stmt_store_result($stmt);

// check whether the SELECT query returned any row or not
if(mysqli_stmt_num_rows($stmt)){
    // bind result variables
    mysqli_stmt_bind_result($stmt, $username, $hashed_password, $regkey, $banned);

    // fetch value
    mysqli_stmt_fetch($stmt);

    if(password_verify($password, $hashed_password)){
        echo json_encode(array('result' => 'success', 'regkey' => $regkey, 'banned' => $banned));
    }else{
        // incorrect password
    }
}else{
    // no results found
}

mysqli_stmt_close($stmt);

// your code

Upvotes: 1

Marc B
Marc B

Reputation: 360892

$data = mysqli_query($GetPassword);
 ^^^---mysqli result handle/object


if(password_verify($password, $data['password'])) {
                                   ^^^^^^^^^^^^---no such element in mysqli

You never fetched your data results, so you're comparing the entered password against a non-existent element of the $data result object/handle.

You need

$row = mysqli_fetch_assoc($data);
password_verify(..., $row['password']);

Most likely you're running with error_reporting and display_errors disabled, meaning you'd never see the "undefined index" warnings that PHP would ave been throwing everytime you ran this code. Those settings should NEVER be off on a devel/debug system.

And note that you're vulnerable to sql injection attacks, so your "security" system is anything but -it's entirely useless and trivially bypassable.

Upvotes: 2

Related Questions