PDO Prepared statements and password hashing? - php

ive looked all over the internet to try to solve this problem and i cant find figure it out for the life of me. Really starting to give up.
So basically whenever i login with the correct email and correct password it says incorrect email or password. This only happens whenever i hash the password in the db
Email: test#gmail.com
Password: testtest
Hash: $2y$10$hk3d/GyYvImcxYR.vdC2/.JDIeQeXyKdTSPifueAkQNrYVBcMn1Yi
Anyways if someone could help me that would be amazing here is my login.php code.
<?php
require "../private/php/autoload.php";
$error = "";
if($_SERVER['REQUEST_METHOD'] == "POST" && isset($_SESSION['token']) && isset($_POST['token']) && $_SESSION['token'] == $_POST['token']){
$email = $_POST['email'];
if(!preg_match("/^[\w\-]+#[\w\-]+.[\w\-]+$/", $email)){
$error = "Please enter a valid email.";
}
$password = $_POST['password'];
if ($error == ""){
$arr['email'] = $email;
$arr['password'] = $password;
$query = "SELECT * FROM users WHERE email = :email && password = :password LIMIT 1";
$stm = $conn->prepare($query);
$check = $stm->execute($arr);
if($check){
$data = $stm->fetchAll(PDO::FETCH_OBJ);
if(is_array($data) && count($data) > 0){
$data = $data[0];
if (password_verify($_POST['password'], $data->password)){
$_SESSION['username'] = $data->username;
$_SESSION['user_id'] = $data->user_id;
header("Location: index.php");
die;
}
}
}
}
$error = "Wrong email or password!";
}
$_SESSION['token'] = get_random_string(30);
?>```

Your MySQL table contains the password hashed, but you're querying it passing through the un-hashed password which is why it's not matching/working presently.
Also, worth noting that this could be bad from a security point of view as the plaintext password is being transmitted and could easily end up in your MySQL logs (Slow Log, Error if there was any issue etc.).
Swap the query out to just look up on the email address alone (assuming it's unique), and then verify the password hashes match in your PHP logic against the MySQL result.

Related

Php Login System Password Hash & Password Verify

I'm trying to make a login system (already have registration system complete) with password_hash() and password_verify() but it isn't working for me. I've been trying to find an answer this whole morning and yet can't seem to make it work, I've watched codecourse tutorials, read blog posts and nothing. The tutorial I've been following the most is this one.
<!-- login -->
<?php
if($_SERVER['REQUEST_METHOD'] == "POST") {
$errors = array();
error_reporting(E_ALL);
ini_set('display_errors', 1);
//Basic validation
if(empty($_POST['username'])){
$errors[] = "Please enter your username";
}else{
$username = $mysqli->real_escape_string($_POST['username']);
}
if(empty($_POST['password'])){
$errors[] = "Please enter your password";
}else{
$password = trim($_POST['password']);
}
if (empty($errors)) {
$sql = "SELECT * FROM users WHERE username = '$username'";
$result = $mysqli->query($sql);
if ($result->num_rows === 1) {
$row = $result->fetch_array(MYSQLI_ASSOC);
if(password_verify($password, $row['password'])) {
echo 'test';
$_SESSION['user']['user_id'] = $row['user'];
header("Location: google.com");
exit();
}else{
$errors[] = "The username or password do not match";
}
}else{
$errors[] = "The username or password do not match";
}
}
}
?>
<!-- register -->
<?php
if($_SERVER['REQUEST_METHOD'] == "POST") {
$username = mysqli_real_escape_string($conn, $_POST['username']);
$password = $_POST['password'];
$hashed_password = password_hash($password, PASSWORD_DEFAULT);
$confirm_password = mysqli_real_escape_string($conn, $password);
$ip = $_SERVER['REMOTE_ADDR'];
if(empty($username) || empty($password) || empty($confirm_password)) {
$error = "Fill in the missing fields";
} else {
$sql = "INSERT INTO users VALUES('', '$username', '$hashed_password', '$ip', 'User')";
if($conn->query($sql) === TRUE) {
$error = "Your account has been created.";
} else {
$error = "Your account has not been created, please try again later.";
}
}
}
?>
The end result product is supposed to login in successfully and redirect, I'm using PHP 5.6 and running on localhost XAMPP.
You'll never get a match because you're using
$password =mysqli_real_escape_string($conn, $_POST['password']);
to store the password and then not using it on verification. Instead you use
$password = trim($_POST['password']);
Make sure you don't escape passwords or use any other cleansing mechanism on them before hashing. Doing so changes the password and causes unnecessary additional coding. The password_hash() function can generate some very lengthy text (the current default is 60 characters), so make sure the field in your database is large enough to accommodate the hash. Setting the field larger now will allow for the length needed. The PHP team is adding more algorithms to the method which means the hash can and will grow.

Whats wrong in this code? im trying to make a login page

I'm trying to make a login page, but it keeps saying username and password not found even though I have entered correct info from the database.
if(isset($_POST['submit'])){
$errMsg = '';
$username = $_POST['username'];
$password = $_POST['password'];
if($username == '')
$errMsg .= 'You must enter your Username<br>';
if($password == '')
$errMsg .= 'You must enter your Password<br>';
if($errMsg == ''){
$conn=new PDO("mysql:host:localhost;dbname=database",'root','');
$stmt = $conn->prepare('SELECT id,username,password FROM admin WHERE username = :username');
$stmt->bindParam(':username', $username);
$stmt->execute();
$stmt = $stmt->fetch(PDO::FETCH_ASSOC);
if(count($stmt) > 0 && password_verify($password, $stmt['password'])){
$_SESSION['username'] = $stmt['username'];
header('location:welcome.php');
exit;
}else{
$errMsg .= 'Username and Password are not found<br>';
}
}
}
As you had said: "I manually created a database and inside table admin i gave username root and password root 36"
password_verify function verifies that a password matches a hash.
But you are passing in a string as the second argument of password_verify function. That's why it doesn't find matches.
You should save password into admin table as a hash using password_hash function:
// saving password
password_hash("root 36", PASSWORD_DEFAULT);
...
// verifying password
...
if(count($stmt) > 0 && password_verify($password, $stmt['password'])){
...
http://php.net/manual/en/function.password-hash.php
http://php.net/manual/en/function.password-verify.php

Issues Verifying Login access with Bcrypt Password Even After calling the verification function

And here's the latest change to my login process. I want to verify if the user's input matches with the hashed password that has been stored in the database.
if(!isset($error)){
//Use the input username and password and check against 'users' table
$query = mysql_query("SELECT * FROM users
WHERE username = '".mysql_real_escape_string($user_input)."' OR email = '".mysql_real_escape_string($user_input)."' LIMIT 1")
or die(mysql_error());
$count_row = mysql_num_rows($query);
$row = mysql_fetch_assoc($query);
if($count_row == 1){
$hashed_password = $row['password'];
if(! password_verify($password, $hashed_password)){
$error[] = "Login failed! Please check your entered email and/or password";
} else if($row['active'] < 1){
$error[] = "Account has not been activated.";
}else if($row['active'] == 1){
// Do nothing
} else {
//write user data into PHP SESSION
This is my latest code. Any help is appreciated. Thanks in advance.
You're hashing the user password with this :
$password = password_hash($password, PASSWORD_BCRYPT);
However, during the login phase, you're doing the following :
$password = strtolower($email) . $password;
Since you're comparing the hashed of two different String, you won't get what you want.

PHP If logic being skipped?

I'm having some problems with this login script, I've already had someone else look it over for me and we cannot seem to figure out what the issue is.
What's happening is when a user tries to login, if the the username is correct it will check if the password is correct and if the password is correct it updates the last access date and redirects like it is supposed to. However if the username is correct and the password is incorrect. It should empty out the password, and let the user know the password they entered is incorrect.
What actually happens when the password is incorrect, is it is skipping to the outermost else statement, and emptying out the username and password and saying there is an issue...whether or not the username entered is correct (regardless of whether or not the password is right).
I have no idea what is happening here, and hopefully someone can help me shed some light on it.
Thank you!
$selectUser = pg_prepare($dbConnection, "selectuser_query", 'SELECT * FROM users WHERE user_id = $1 AND password = $2');
<?php
$error = "";
$username_error = "";
$password_error = "";
if($_SERVER["REQUEST_METHOD"] == "GET")
{
$login = "";
$password = "";
}
else if($_SERVER["REQUEST_METHOD"] == "POST")
{
$login = trim($_POST["login"]);
$password = trim($_POST["password"]);
if(!isset($login) || $login == "")
{
$username_error = "You must enter your user name to login!";
}
if (!isset($password) || $password == "")
{
$password_error = "You must enter your password to login!";
}
if(($error == "") && ($password_error == "") && ($username_error == ""))
{
$selectUser = pg_execute($dbConnection, "selectuser_query", array("$login", "$password"));
if($login == pg_fetch_result($selectUser, "user_id"))
{
if($password == pg_fetch_result($selectUser, "password"))
{
$date = date("n-j-Y");
$updateDateAccess = pg_execute($dbConnection, "updatedate_query", array("'$date'", "$login"));
header('Location: ./welcome.php');
}
else
{
$password = "";
$error = "The password is incorrect. Please try again.";
}
}
else
{
$login = "";
$password = "";
$error = "The username/password is incorrect. Please try again.";
}
}
}
?>
Your problem is your query:
SELECT * FROM users WHERE user_id = $1 AND password = $2
It checks both the username and password, which results in no records being returned if the password is incorrect. Thus, the next if condition isn't satisfied:
$selectUser = pg_execute($dbConnection, "selectuser_query", array("$login", "$password")); // no records
if($login == pg_fetch_result($selectUser, "user_id")) // not satisfied, because there are no records
{
// ...
}
else // this runs
{
$login = "";
$password = "";
$error = "The username/password is incorrect. Please try again.";
}
What you want to do is run a query that retrieves the (salted and hashed) password for a given username, then check the password in your application logic.
Also, as others have pointed out in the comments, this is not a good way to store passwords or respond to incorrect info. It looks like the passwords are in plain text, but they should be hashed and salted. Also, you should not tell the user which part of the information was incorrect; otherwise, you let an attacker determine valid usernames and then focus on brute-forcing those.

php user login anf function

if(isset($_POST['login'])) {
$username = mysql_real_escape_string($_POST['username']);
$password = mysql_real_escape_string($_POST['password']);
if(empty($username) || empty($password)) {
$error = 1;
$error_message = 'Please fill in all the required fields.';
} else {
get_login_name($username, $password);
//The commented line works...
//$query = mysql_query("SELECT /* user_logged true, page login */username, password FROM members WHERE username = '".$username."' AND password = '".sha1($password)."' LIMIT 1");
}
if(mysql_num_rows(get_login_name($username, $password)) == 0) {
echo get_login_name($username, $password);
$error = 1;
$error_message = 'Incorrect username or password.';
} elseif ($error == 0) {
//Other stuff....
}
}
Function:
function get_login_name($password, $username) {
global $myDB;
global $config;
$query = "SELECT /* page == login, functions.php */username, password FROM members WHERE username = '".$username."' AND password = '".sha1($password)."' LIMIT 1";
$result = $myDB->Execute($query) or die(GetDbError($myDB->ErrorMsg()));
return $result;
}
How properly check if username or password incorrect ? (part if(mysql_num_rows(g.....)
In my opinion something wrong i have done ir function get_login_name with return and checking. By the way, using adodb.
EDIT:
After all i decided a bit test it, so, let's leave function as it now and let's check username and password part:
if (!is_null(get_login_name($password, $username))) {
echo get_login_name($password, $username);
$error = 1;
$error_message = 'Incorrect username or password.';
}
If username or password incorrect ir gives me:
username,password which mean result doesn't found at all (no user, if user correct gives same)
Ok, let's enter valid user and pass, and it gaves:
username,password zero,0a706ce75f3bc195c8ed7be5a21d3766abb0d384
What's wrong ?
Essentially, if get_login_name has a return, that means the query returned a match for username and password which means the combination is correct, otherwise, no result means there's no match so you could say either username or password is incorrect (because they don't exist or one of them is wrong). If $Result has a value using get_login_name would likely to be just:
if (!is_null(get_login_name($password, $username)))
// correct
else
// incorrect
Play around with it and see the results.
Ech, after testing managed it to work :)
That seems this part fails :/
if (!is_null(get_login_name($password, $username)))
So, hole code:
if (!$myDB->Affected_Rows()) {
//if(mysql_num_rows($query) == 0) {
$error = 1;
$error_message = 'Incorrect username or password.';
}
What i have ? Just changed it to:
if (!$myDB->Affected_Rows()) {
Thank you all guys who tryed help.

Categories