Rik Pronk
Rik Pronk

Reputation: 11

Updating field validates password?

Okay, so as a side project for my education, I'm currently working on a secure login system using PHP and mysqli. It's been going smoothly, but now I encountered an issue my peers, teachers and I are baffled by.

I'm hashing and checking my passwords via password_hash and password_verify.

When I create an account, everything gets stored in the database correctly. Then, when I try to login, using the correct password, it's giving me an error that my password isn't corect.

Now here's the kicker: When I go into PHPMyAdmin, copy the hashed password stored in the database, and update the password field with that excact copied password... it works. I can login as intended, with the password I used, and it won't give me any errors.

Does anyone have an idea what's up, and how to fix it?

Code used for registering:

public function createAccount()
{
    global $con;

    $this->password = password_hash($this->password, PASSWORD_DEFAULT)."\n";
    $sql='INSERT into user (username, password, email, creation_date)
        VALUES (?,?,?,?)';

    // Prepare statement
    $stmt = $con->prepare($sql);
    if($stmt === false) {
      trigger_error('Wrong SQL: ' . $sql . ' Error: ' . $con->error, E_USER_ERROR);
    }

    // Bind parameters. Types: s = string, i = integer, d = double,  b = blob
    $stmt->bind_param('ssss',$this->username,$this->password,$this->email,$this->creationDate);

    // Execute statement
    $stmt->execute();

    echo $stmt->insert_id;
    echo $stmt->affected_rows;

    $stmt->close();

    $_SESSION['login'] = true;
    $_SESSION['username'] = $username;
    Header("Location: index.php");
}

Code used for validating credentials:

public function fetchCredentials() {
    // Select a set of credentials from the username given in form and return as array
    global $con;
    $sql = 'SELECT id, password FROM user WHERE username = ?';

    // Prepare statement 
    $stmt = $con->prepare($sql);
    if($stmt === false) {
      trigger_error('Wrong SQL: ' . $sql . ' Error: ' . $con->error, E_USER_ERROR);
    }

    // Bind parameters. Types: s = string, i = integer, d = double,  b = blob
    $stmt->bind_param('s',$this->username);

    // Execute statement
    $stmt->execute();

    // Store all results in an array
    $rs=$stmt->get_result();
    $arr = $rs->fetch_all(MYSQLI_ASSOC);
    $stmt->close();

    return($arr);
}

public function validateCredentials() {
    // Get credentials
    $arr = $this->fetchCredentials();

    // Validate username
    if (count($arr) > 1) {
        $this->error = 'crit';
        $this->abort = true;
    } else if (count($arr) < 1) {
        $this->error = 'badLogin';
        $this->abort = true;
    } else {
        $arr = $arr[0];
    }

    echo $arr['password'].'<br>'.$this->password;
    // Validate password. NOTE: This is where the issue arises. Password_verify() will return false where it    should return true.
    if ($this->abort == false && !password_verify($this->password, $arr['password'])) {
        $this->error = 'badLogin';
        $this->abort = true;
    }

    // Return values if needed
    if ($this->abort == false) {
        $this->id = $arr['id'];
    }
    return $this->abort;
}

Part that calls the logging in: (Yes, the validatecredentials function is getting called twice. Yes, there are some other things in there that aren't very well-written. This part of the code still needs some work and it's the first thing I'll do after fixing the issue above)

function login()
{
    $newCred = new credentials(
    $_POST['username'],
    $_POST['password']);

    if ($newCred->checkForm() == false
    && $newCred->validateCredentials() == false) {
        $newLogin = new login(
        $newCred->validateCredentials()['id']);

        $newLogin->login();
        $newLogin->getUserDetails();
    } else {
        $newCred->fetchError();
    }
}

Upvotes: 0

Views: 53

Answers (1)

Rik Pronk
Rik Pronk

Reputation: 11

Okay, to everyone who helped: Thanks. I was just helped by my classmate and he managed to find the problem. I am hitting myself right now.

$this->password = password_hash($this->password, PASSWORD_DEFAULT)."\n";

Here it is. "\n". A newline. I grabbed my code from an example, and that was in there for some reason. When I updated the database, the newline got deleted.

Upvotes: 1

Related Questions