Unhashed password in PHP [duplicate] - php

This question already has an answer here:
Verifying password_hash() in PDO prepared statements
(1 answer)
Closed 7 months ago.
how I can put my variable $passHash from register function to login function
I need that cause I try to use password_verify() method which required my hash
I try additional got my hashe password from database and put to the password_verify() but it not working.
public function register($uname, $email, $pass) {
$passHash = password_hash($pass, PASSWORD_DEFAULT);
$sqlQuery="INSERT INTO UserData (userName, userEmail, userPassword) VALUES (:userName,:userEmail,:userPassword)";
$stmt = $this->db->prepare($sqlQuery);
$stmt->bindparam(':userName', $uname);
$stmt->bindparam(':userEmail', $email);
$stmt->bindparam(':userPassword', $passHash);
if($stmt->execute()) {
return true;
} else {
return $stmt->error;
}
}
public function login($emailUser,$passUser){
$sqlQuery= "SELECT * FROM UserData WHERE userEmail=? AND userPassword=? ";
// $sqlQuery.Id;
$stmt = $this->db->prepare($sqlQuery);
$stmt->execute([$emailUser, $passUser]);
$result = $stmt->fetch(PDO::FETCH_ASSOC); <-- NOT WORKING SO I try get hash variable from register function
$checkPassword=password_verify($passUser,$result["userPassword"]);
if($checkPassword==true){
if($stmt->rowCount()==0){
echo "err";
}else{
echo "success";
}
}else{
echo 'bad pass';
}
}

Steps to run a successful login attempt:
Collect the username/identifier from the login client.
$emailUser = $_POST['email'];
$passUser = $_POST['password'];
Send only that to the MySQL to retrieve only that row, including the hashed password and the row identifier.
SELECT UserId, userPassword FROM UserData WHERE userEmail=?
Using PHP check the hashed password from the database matches the value given by the user
if(password_verify($passUser, $result['userPassword']){
...
allow access....
NEVER send the password to MySQL, it's worthless.
Use $stmt->fetchAll(); to retrieve the data row
It is bad practise to do SELECT * instead you should select the columns you actually want to use.
your $stmt->rowCount()==0 clause will always fail, because it is after the password has been tested and passed, so remove this whole section.
It is bad practise to tell people specifically their password has failed, as this can be used to fish for if someone has an email on this system. Instead state "Your email OR password are incorrect" so it can't so easily be established by 3rd parties if a certain persons email is on a system.

Related

Why is my prepared statement on my login page not working? [duplicate]

This question already has answers here:
What to do with mysqli problems? Errors like mysqli_fetch_array(): Argument #1 must be of type mysqli_result and such
(1 answer)
Reference - What does this error mean in PHP?
(38 answers)
Closed 2 years ago.
I have created a login page however I'm having a hard time authenticating the user. I am able to establish a connection however my sanitation is not working. I'm not sure if its the select statement or HTML related. I've played around with different SELECT statements and troubleshooted the code further up but that doesn't seem to be the problem.
<?php
// Now I check if the data from the login form was submitted, isset() will check if the data exists.
if (!isset($_POST['username'], $_POST['user_password'])) {
echo 'error2';
// Could not get the data that should have been sent.
exit('Please fill both the username and password fields!');
}
// Prepare our SQL, preparing the SQL statement will prevent SQL injection.
if ($stmt = $con->prepare("SELECT id, username, user_password FROM user_info WHERE username = ?")) {
// Bind parameters (s = string, i = int, b = blob, etc), in our case the username is a string so we use "s"
$stmt->bind_param('s', $_POST['username']);
$stmt->execute();
// Store the result so we can check if the account exists in the database.
$stmt->store_result();
if ($stmt->num_rows > 0) {
$stmt->bind_result($id, $user_password);
$stmt->fetch();
// Account exists, now we verify the password.
// Note: remember to use password_hash in your registration file to store the hashed passwords.
if (password_verify($_POST['user_password'], $user_password)) {
// Verification success! User has loggedin!
// Create sessions so we know the user is logged in, they basically act like cookies but remember the data on the server.
session_regenerate_id();
$_SESSION['loggedin'] = true;
$_SESSION['name'] = $_POST['username'];
$_SESSION['id'] = $id;
echo 'Welcome ' . $_SESSION['name'] . '!';
} else {
echo 'Incorrect password!';
}
} else {
echo 'Incorrect username!';
}
$stmt->close();
} else {
echo 'error3';
}
You're selecting 3 columns in SELECT id, username, user_password but you're only binding two variables in $stmt->bind_result($id, $user_password);. This mismatch will cause an error.
There's no need to select username since that's the column you're matching in the WHERE clause. Change the select list to SELECT id, user_password to match the variables you're binding.

Trying to verify a hashed password from database with password from login form

I am making a registration and login form, which asks for the user's email and password. In my registration file I hashed the password provided by the user, and stored it in the database, with the function password_hash. In my login form I tried to verify the password provided by the user with the stored hashed password in the database, but it fails. I used the password_verify function. Here is a snippet of the registration code:
Registration file snippet
if(!isset($error)){
//hash the password
$hashedpassword = password_hash($_POST['password'], PASSWORD_DEFAULT);
echo $hashedpassword;
try {
$sql = "INSERT INTO users (mail, password, province) VALUES (:mail, :password, :province)";
$stmt = $db->prepare($sql);
//Bind variables
$stmt->bindValue(':mail', $mail);
$stmt->bindValue(':password', $hashedpassword);
$stmt->bindValue(':province', $province);
//Execute the statement and insert the new account.
$result = $stmt->execute();
//If the signup process is successful.
if($result){
echo $hashedpassword;
exit;
}
}
catch(PDOException $e) {
$error[] = $e->getMessage();
}
}
Hashed passwords in database
For these passwords I get the following hashed passwords, which are stored in the database:
football:
$2y$10$q0Y8Mfdl75Dt8op7WaqQM.t5y4LMO6gfYwmbycL1xRMiUUQu8dtWm$2y$10$q0Y8Mfdl75Dt8op7WaqQM.t5y4LMO6gfYwmbycL1xRMiUUQu8dtWm
cricket:
$2y$10$Pyoz1XC0skRjHLjxHdrYYeYplY98w4uOp23QpZb/VNN0y41/6YPJC$2y$10$Pyoz1XC0skRjHLjxHdrYYeYplY98w4uOp23QpZb/VNN0y41/6YPJC
The type for the password row is varchar(255) and the collation is utf8mb4_general_ci The passwords are stored like this:
$2y$10$q0Y8Mfdl75Dt8op7WaqQM.t5y4LMO6gfYwmbycL1xRM...
$2y$10$Pyoz1XC0skRjHLjxHdrYYeYplY98w4uOp23QpZb/VNN...
When I hover over the passwords it says 'Original length 60'.
Login file snippet
This is a snippet of my login file code:
$mail = htmlspecialchars_decode($_POST['mail'], ENT_QUOTES);
if(!filter_var($mail, FILTER_VALIDATE_EMAIL) and !empty($_POST['mail'])) {
$error[] = 'Please enter a valid email address';
}
$stmt = $db->prepare('SELECT mail, password FROM users WHERE mail = :mail');
$stmt->execute(array(':mail' => $mail));
$row = $stmt->fetch(PDO::FETCH_ASSOC);
if(!empty($row['mail'])){
$error[] = 'Email provided is good.';
}
$password = $_POST['password'];
$stmt = $db->prepare('SELECT password FROM users WHERE password = :password');
$stmt->execute(array(':password' => $password));
$row = $stmt->fetch(PDO::FETCH_ASSOC);
$checkpass = $row['password'];
echo $checkpass;
if(password_verify($password, $row['password'])) {
$error[] = 'Password provided is good.';
}
Checking whether the email can be found in the database works fine, as it gives me the error message (which I need to change to a normal message).
But I can't get the password verification working. I tried to see what the code pulls out the database with $checkpass = $row['password']; and
echo $checkpass;
But it doesn't return anything (maybe because it only returns a 0 or 1 value?).
Maybe it has to do something with the way I try to select the hashed password out of the database? Or the way I insert them in the database, or the MySQL table options? It may be a simple fix but I tried many different things and I couldn't get it to work.. Hope you guys can help!
The second query seems to be useless since in the first query you already select the mail and password fields. So you should just need to execute the first query, check if the user is valid and then check the password with the password_verify method.
Your second query fails (probably) because in the condition you pass the cleartext but in the DB there is the hashed password so you will never find anything. To check print the second query before the execution.
Before executing query for password check in login you should create hashed password for the input password and that hashed password need to be compared

How to select a hashed password from mysql db [duplicate]

This question already has answers here:
How do I use password hashing with PDO to make my code more secure? [closed]
(3 answers)
Closed 5 years ago.
Okay, so I'm trying to make a register/login code for my personal website.
I had no troubles making the registration form but I'm having some difficulties with the login.
Here's a part of my code:
$stmt = $pdo->prepare("SELECT password FROM members where username = ? ");
$stmt->bindValue(1, $username);
$stmt->execute();
Now to my understanding i need to fetch the first row from my table convert it to a string and then using password_verify to compare that string to whatever the users inputs in the form i created. The problem i have is that it fetches an array and can't really use password_verify to compare a string to an array.
Am I doing something wrong? how should I do this?
tl; dr How do I actually select a hashed password from DB, convert it to a string and then compare that string with the password my user will input.
Thanks.
This library works on
PHP 5.5+: use password_hash
$sql = "SELECT * FROM members WHERE username = ?";
$stmt = $pdo->prepare($sql);
$result = $stmt->execute([$_POST['username']]);
$users = $result->fetchAll();
if (isset($users[0]) {
if (password_verify($_POST['password'], $users[0]->password) {
// valid login
} else {
// invalid password
}
} else {
// invalid username
}

PHP password_verify not working need to get result DOMAIN SPECIFIC

So in my function I have the connection, the query which will result in 1 row and 1 column displayed. I then want to run the password_verify() This is where I am struggling. As the first parameter I have placed $pass which is user entered but then I need to get the result from the database to place in the 2nd parameter.
How would I do this?
function login($user, $pass){
$conn = connect();
$query = "SELECT password FROM account WHERE username = '$user' AND password = '$pass'";
$result = mysqli_query($conn, $query);
if (mysqli_num_rows($result)=== 1){
password_verify($pass, "$row[password]");
session_start();
If you do everything right your password field in a account table stores hashed password.
And argument $pass of a function is a plain password, I suppose.
So, your query
SELECT password FROM account WHERE username = '$user' AND password = '$pass'
will NEVER find any user, as you try to find user by plain password.
In addition - your $row variable is not defined.
What's the solution:
function login($user, $pass){
$conn = connect();
// do not add password to query
$query = "SELECT password FROM account WHERE username = '$user'";
$result = mysqli_query($conn, $query);
if (mysqli_num_rows($result) === 1){
// define $row
$row = mysqli_fetch_assoc($result);
// set proper quotes and compare password
// from db with password input by user
if (password_verify($pass, $row["password"])) {
// do something if password is correct
session_start();
And of course, instead of passing values directly to query, start using prepared statements.
When someone registers on your website, you have to use de built-in PHP function password_hash(). Also, I suggest naming it "password_hash" in your database and not "password" as to avoid confusion.
When someone tries to log in on your website, you have to use the built-in PHP password_verify() to compare the hashed password with the password.
// Login function
function login($user, $pass)
{
// Search the user by username
$conn = connect();
$query = "SELECT password_hashed FROM account WHERE username = '$user'";
$result = mysqli_query($conn, $query);
if (mysqli_fetch_row($result))
{
// We found the user, check if password is correct
if(password_verify($pass, $result["password_hashed"]))
{
return true;
}
else
{
return false;
}
}
else
{
// We didn't find the user
return false;
}
}
-Why should you hash the password when you store it into the database? Because when you store the password without hashing, the password in the database is exactly the same like what the user types in when registering. So when a hacker gets into the database, he sees the passwords of every user. If you hash the password, PHP makes the password into something completely else, that way when a hacker gets into the database he doesn't see the password but something completely else.
-The password_verify function is definitely the way to go when a user logs in. Just don't forget to add extra security when you enter data you receive from a user (through $_POST, $_GET, $_SESSION, ...) because when a user types in the follow name: my name" DROP TABLES account; they will delete all account informations.

I've got a mysql/php hash(sha1) login issue

I have a issue regarding logging in with password being hashed in database.
My current script just tells me 'bad password' message even when its correct.
$s = $mysqli->query("SELECT * FROM `users` WHERE email`='".$_POST['email']."'") or die();
$i = $s->fetch_assoc();
if($_POST['password'] == sha1($i['password'])) {
echo "works";
} else {
echo "bad password";
}
You are doing it the wrong way round. The database password is already hashed I hope but the user enters a plain text password, so you need to hash what the user enters and see if that matches the hash you have on the database
$s = $mysqli->query("SELECT * FROM `users` WHERE `email`='{$_POST['email']}'") or die();
$i = $s->fetch_assoc();
if(sha1($_POST['password']) == $i['password']) {
echo "works";
} else {
echo "bad password";
}
However
Please dont roll your own password hashing. PHP provides password_hash()
and password_verify() please use them, I might want to use your site one day
And here are some good ideas about passwords
If you are using a PHP version prior to 5.5 there is a compatibility pack available here
Also
Your script is at risk of SQL Injection Attack
Have a look at what happened to Little Bobby Tables Even
if you are escaping inputs, its not safe!
Use prepared statement and parameterized statements
Here is an example of how you can verify sha with mysql safely.
<?php
// Basic php MYSQL authentication with crypted password
$username = $_POST['username'];
$password = $_POST['password'];
$salt = "CrazyassLongSALTThatMakesYourUsersPasswordVeryLong123!!312567__asdSdas";
$password = hash('sha256', $salt.$password);
//echo $password;
// Mysql connection
$mysqli = new mysqli("localhost","mysqluser","mysqlpassword","mysqldatabase");
$stmt = $mysqli->prepare('SELECT userid FROM Users WHERE password = ? AND username = ?');
// (ss -> string, string) Always bind parameters and use prepared statement to improve security
$stmt->bind_param("ss", $password, $username);
$stmt->execute();
$stmt->bind_result($userid );
if (!empty($stmt->fetch())) {
// if fetch is not empty we have results and password hash was correct
echo "User was found";
} else
echo "User was not found";
$mysqli->close();
?>

Categories