Password_hash Incorrect after updating table - php

My login system md5 hashes the username and I password_hash the password. Therefore I cannot fetch the row based on the username? My client then enters an email address which I base64encode. I then offer a lost password change option. However, when I UPDATE the field using the same type of hash but, using the email field as an identifier, the new password is incorrect?
Below is a sample of my UPDATE, but hard coded for illustration(PS this does not work either?).
$em = 'example#example.com';
$em1 = base64_encode($em);
$ps = 'some password';
$password_hash = password_hash($ps, PASSWORD_BCRYPT);
$qu = "UPADTE table SET field = '$password_hash' WHERE email = '$em1'";
$res = mysqli_query($link, $qu);
Edited question to include my code after verifying that the user exists and sending out an email for them to positively identify themselves as the owner of the account. Here is the final processor page.
if(EMPTY($_POST[psw1]) ) {
echo "New password must be supplied"; }
elseif(EMPTY($_POST[psw2]) ) {
echo "Repeat password must be entered"; }
elseif($_POST[psw1] != $_POST[psw2]) {
echo "Passwords entered do not match";
} elseif(EMPTY($_POST[eu])) {
echo "Essential data is missing in order to complete this process.";
}
elseif (strlen($_POST['psw1']) < 6) {
echo "Password must be at least six characters in length";
}
elseif (preg_replace("/[^a-zA-Z0-9]/", "", $_POST['psw1']) != $_POST['psw1']) {
echo "Password may only contain letters and numbers";
}
elseif(!EMPTY($_POST[psw1]) && !EMPTY($_POST[psw2]) && !EMPTY($_POST[eu]) && $_POST[pw1] == $_POST[pw2] ) {
include "conn.php";
echo "$_POST[eu]<br />";
$eu = $_POST[eu];
$pdw = password_hash($_POST[pw1], PASSWORD_BCRYPT);
$sq = mysqli_query($link, "UPDATE str1 SET pf = '$pdw', cu_pw_status = '2' WHERE cu_type = '$eu'");
echo "Your password has been changed, you may now login <a href='login2.php'>Login</a>";
} else {
echo "An error occured. Contact Site Admin"; }

Check if you have column 'field' in your users table. Seems suspicios.
Check your update string, now it misses table name.
Check if you have user before updating:
$exists = mysqli_query("SELECT id FROM users WHERE email='$em1');
if (!is_empty($exists)) {
mysqli_query("UPDATE TABLE users SET password = '$ps' WHERE id='$exists');
echo 'updated' . "\n";
} else {
echo 'no user with such email hash' . "\n";
}

Related

Login count in php

I have a login script I want if user attempt 3 invalid password then the username associated to them would be disabled or blocked for a day / 24hrs.
Since I make a if condition in php login code where status=3 alert your account is blocked for a day.
status is my database column name which count the value of invalid login of user from 1 to 3 maximum.
But issue is my here that is how I make the status automatically count or increase like 1, 2, 3 in user invalid login.
How to I add this function with my login code
I have not idea about that. On YouTube there is not any video regards this even in other website.
Stackoverflow is my last hope where someone helps user.
Please have a look at this question and help to create satatus count automatic when user inter invalid password.
My login PHP is : https://pastebin.com/QpwDtjBg
Thank you in advance
You're gonna want to use PHP's $_SESSION object.
In the code block where you detect bad user/pass combos, add an iterator to the session.
First, add a session entry to the top of your script (Or wherever you define global variables), for bad_logins, and start your session.
session_start();
$_SESSION['bad_logins'] = 0;
Then in the part of your code where you detect a bad login, increment the bad logins by 1.
$_SESSION['bad_logins']++;
This will allow you to then check for bad attempts with an if statement
if($_SESSION['bad_logins'] > 3) {
// Do something here.
}
The script you linked has some other issues you may want to address prior to adding this in though.
You just need to add an update to the field 'status' on the database with 1, 2 or 3, on the IF condition:
if($data == NULL || password_verify($password, $data['Password']) == false) {
And read that same field, when the submit form is sent every single time... if it is already 3, then just skip to the IF condition
if($data['Status'] == "//auto count//")
Something like this (haven't tested the code) and the code should be function based, at least...
`
<?php
error_reporting(E_ALL);
ini_set("display_errors", 1);
if(isset($_POST['submit'])) {
$messages = array(
'INVALID_EMAIL' => "<div class='alert-box warning error'><span>Invalid format, re-enter valid email.</span></div>",
'ALL_FIELDS_REQUIRED' => "All field is mandatory! case sensitive.",
'VERIFY_EMAIL' => "Please verify your email!",
'INVALID_COMBINATION' => "Invalid username or password combinations.",
'BLOCKED' => "you are blocked for a day. <a href='#'><span>Know why?<span></a>",
);
$msg = "";
$error = false;
$con = new mysqli("localhost", "softwebs_softweb", "test#123", "softwebs_cms");
$email = $con->real_escape_string(htmlspecialchars($_POST['username']));
$password = $con->real_escape_string(htmlspecialchars($_POST['password']));
if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
$msg = $messages['INVALID_EMAIL'];
$error = true;
}
if ($email == "" || $password == "") {
$msg = $messages['ALL_FIELDS_REQUIRED'];
$error = true;
}
if(!$error) {
$sql = $con->query("SELECT * FROM users where Email_ID = '$email' ");
if ($sql->num_rows > 0) {
$data = $sql->fetch_array();
// Blocked
if ($date['status'] === 3) {
$msg = $messages['BLOCKED'];
$error = true;
}
if ($data['isEmailConfirm'] == "0") {
$msg = $messages['VERIFY_EMAIL'];
$error = true;
}
if ($data == NULL || password_verify($password, $data['Password']) == false) {
$msg = $messages['INVALID_COMBINATION'];
$error = true;
// Update the status + 1
$sql = $con->query("UPDATE users SET status = " . $statusData['status'] + 1 . " WHERE Email_ID = '$email' ");
}
}
}
if($error && trim($msg) !== "") {
$msg = "<div class='alert-box error'><span>$msg</span></div>";
} else {
session_start();
$_SESSION['login']=$_POST['username'];
$_SESSION['id']=$data['id'];
header('location: ./account/dashboard.php');
}
}
?>
`

basic error with password encryption in php

I want to reset user password using php. i got user's current and new password from html form . here's php script to reset password. But it always executes else part even if user enters correct password. how?any solution? i know there might be a simple error but i'm new at this and couldnt find any error.
$uid = $_SESSION['uid'];
$current_pass = $_POST['org_pass'];
$new_pass = $_POST['new_pass'];
if(isset($_POST['submit']))
{
$act_pass = $db_con->prepare("SELECT password FROM user WHERE u_id= ?");
$act_pass->bindParam(1,$uid);
$act_pass->execute();
$actual_pass = $act_pass->fetchColumn();
define('SALT', 'flyingrabbit');
$typed_pass = md5(SALT.$actual_pass);
if ($typed_pass == $current_pass)
{
$new_pass1 = md5(SALT . $new_pass);
$res = $db_con->prepare("UPDATE user SET password= ? WHERE u_id=?");
$res->bindParam(1,$new_pass1);
$res->bindParam(2,$uid);
$res->execute();
header("Location: profile.php");
exit;
}
else
{
echo "<script type=\"text/javascript\">window.alert(\"You entered wrong password.\");window.location.href = 'profile.php';</script>";
}
}
This looks wrong:
$actual_pass = $act_pass->fetchColumn();
// ...
$typed_pass = md5(SALT.$actual_pass);
if ($typed_pass == $current_pass)
You are hashing the information you got from the database which - I assume - is already hashed.
You probably want:
$actual_pass = $act_pass->fetchColumn();
// ...
$typed_pass = md5(SALT.$current_pass);
if ($typed_pass == $actual_pass)
Note that md5 is not recommended to hash passwords.
You should compare hashed $current_pass and **$actual_pas**s.
Replace
$typed_pass = md5(SALT.$actual_pass); with $typed_pass = md5(SALT.$current_pass);
$typed_pass == $current_pass with $typed_pass == $actual_pass
It goes to the else statement because you compare $typed_pass == $current_pass but on the previous line you do this $typed_pass = md5(SALT.$actual_pass) you compare a hashed, salted password to a plain text password

PHP not working, database not updating

im writing this php script to update user passwords, requiring old pasword, new and new confirmation. It all works it seems up to the actual UPDATE mysql statement. Not sure what I've done wrong, al help appreciated!
Also, I am aware its not secure and such, I am just trying ot make it work first im a php newbie!
I'm tearing my hair out, when I run this, everything seems to work except it breaks just before if (empty($error)){ , i have tested the echo for session email and it displays that, however it does not update the database with the new password. Please help! below is my code:
<?php
session_start();
include('database_connection.php');
$error = array();
if (empty($_POST['oldpassword'])){
$error[] ='You did not enter your current password!';
} else {
$oldpassword = $_POST['oldpassword'];
}
if (empty($_POST['newpassword'])){
$error[] = 'You did not enter a new password!';
} else {
if(preg_match("/^.*(?=.{8,})(?=.*[0-9])(?=.*[a-z])(?=.*[A-Z]).*$/", $_POST["newpassword"])){
$newpassword = $_POST['newpassword'];
} else{
$error[] = 'Password must be at least 8 characters and must contain at least one lower case letter, one upper case letter and one digit!';
}
}
if (empty($_POST['newpasswordcon'])){
$error[] = 'You did not enter your new password confirmation!';
} else {
if(preg_match("/^.*(?=.{8,})(?=.*[0-9])(?=.*[a-z])(?=.*[A-Z]).*$/", $_POST["newpasswordcon"])){
$newpasswordcon = $_POST['newpasswordcon'];
} else{
$error[] = 'Password must be at least 8 characters and must contain at least one lower case letter, one upper case letter and one digit!';
}
}
if($_POST['newpassword'] != $_POST['newpasswordcon']){
$error[] ='New password and confirmation do not match!' ;
}
$sql = "SELECT password FROM users WHERE email='" . $_SESSION['email'] . "'";
$result = mysql_query($sql);
if( $r = mysql_fetch_array($result) ) {
extract($r);
if($_POST['oldpassword'] != $password);{
$error[] ='Incorrect current password!';
}
//breaks here
echo $_SESSION['email'];
if (empty($error)){
echo $_SESSION['email'];
mysql_query("UPDATE users SET password='$newpassword' WHERE email='" . $_SESSION['email'] . "'");
echo '<p class ="alert alert-success fade in">Success! Your password has been updated!</p>';
}
} else{
foreach ($error as $key => $values) {
echo '<p class ="alert alert-error fade in">'.$values.'</p>';
}
}
?>
There is a semicolon which should not be there.
if ($_POST['oldpassword'] != $password);{ // <- remove this semicolon after )
$error[] ='Incorrect current password!';
}
I don't see any addslashes() in your code and am wondering if you get any matches? http://www.php.net/manual/en/function.addslashes.php

PHP current password not the same as in database

I create a function to edit user password here the function code.
function updateUser ()
{
$current = md5($_POST['cpassword']);
$new = md5($_POST['npassword']);
$newc = md5($_POST['npasswordc']);
$name = $_POST['username'];
connectDB();
$check = mysql_query("SELECT password FROM user WHERE user_name = '$name'")
or die(mysql_error());
if ($check != $current) {
?> <div id="error">
<?php die('Current password is wrong. Press back to try again.'); ?>
</div> <?php
}
if ($new == $newc) :
$sql = "UPDATE user SET password = '$new' WHERE user_name = '$name'";
execute($sql);
?> <div id="error">
<?php die('Password Successfully Updated. Back to dashboard');
?> </div> <?php
else : ?> <div id="error">
<?php die('New Password did not match. Press back to try again');
?> </div> <?php
endif;
}
the value will be pass by the form on different page, everything seem to work fine. When I try to change password, it say successful, and when I check in the database, the md5 value is changing that mean the password was change.
But when I try to change password of same username, I still need to enter the old password for current password, even though in database it already changed?
What seem to be the problem?
Thank you
$check is a mysql resource, not a value. You might do
if($check && (mysql_num_rows($check) > 0))
{
$res = mysql_fetch_assoc($check);
if($res['password'] != $current) {
Be careful of SQL injections, you should do at least
$name = mysql_real_escape_string($_POST['username']);
before entering it into the query.
Also, md5 is a week hashing algorithm, I strongly suggest you use a SALT, and better hash algos like at the very least sha1() or better go for the sha2 family (sha256, sha512, for ex) or bcrypt
I have changed your code... maybe it works. also watch the comments it explains something maybe it helps:
function updateUser ()
{
$current = md5($_POST['cpassword']);
$new = md5($_POST['npassword']);
$newc = md5($_POST['npasswordc']);
// first check if the passwords matches if not why waist the connection
if ($new == $newc) {
$name = $_POST['username'];
connectDB();
// why not checking your pass in the query
// when a result is zero it means there is no match found
$check = mysql_query("SELECT password FROM user WHERE user_name = '{$name}' AND password = '{$current}'") or die(mysql_error());
$result = mysql_fetch_assoc($check);
// You where checking a resource with a string(MD5)?
if (mysql_num_rows($check) == 0) {
?><div id="error">
<?php die('Current password is wrong. Press back to try again.'); ?>
</div><?php
return false;
} else {
// update the query with the ID you got from the check..
// why? because a ID is always unique
$sql = "UPDATE user SET password = '{$new}' WHERE user_id = '{$result['user_id']}'";
execute($sql);
?><div id="error">
<?php echo 'Password Successfully Updated. Back to dashboard';
?></div><?php
return true;
}
} else {
?><div id="error">
<?php echo 'New Password did not match. Press back to try again';
?></div><?php
return false;
}
}

Query SQL for username and return password [duplicate]

This question already has answers here:
Best way for a 'forgot password' implementation? [closed]
(10 answers)
Closed 2 years ago.
I have a database of usernames and passwords. I need to create a "Forgot password" function and have it search the table for a username and return that user's password. Then I would like it to send an email saying the name and password.
Here is my working code for querying the database for a specific user:
<?php
session_start();
include "config.php";
if($_POST['nameQuery']) {
$query = "SELECT * FROM myDatabase WHERE name = '" .$_POST['nameQuery']. "'";
$result = mysql_query($query);
if (mysql_num_rows($result) > 0) {
//User exists
echo '1';
} else {
mysql_query($query);
//User does not exist
echo '0';
}
}
?>
DO NOT store passwords in your database. Cleartext passwords should never be stored. You should be storing a hash of the passwords to help prevent them being used on other sites. See Best way to store password in database for more information.
Your code is NOT secured ! Your $_POST['nameQuery'] is a gorgeous opened door to SQL Injection
The minimum security is to escape and sanitize all your inputs
$nameQuery = mysql_real_escape_string ($_POST['nameQuery']);
The golden rule: never trust incoming data.
Community Wiki:
Don't. Because that means you'll be saving retrievable passwords. Better to send a password-changing link to their email that gives access to a one-time password reset page. In this way, the password isn't changed until a reset cycle is completed by someone with access to that user's email.
In that way you can appropriately hash passwords and check incoming passwords against a hash only.
In addition, I recommend looking into php's PDO, because you're currently creating sql queries that are succeptible to sql-injection.
I have a few suggestions for you
Don't send people there password but rather provide them with a link to change there password
Look into kjetilh's suggestion
good luck and happy coding
First thing's first: you might want to make sure that you won't get SQL-injected via your login, as you're literally injecting the user input into your query... big no-no.
Swap this:
$query = "SELECT * FROM myDatabase WHERE name = '" .$_POST['nameQuery']. "'";
...for this:
$query = sprintf(
'SELECT * FROM myDatabase WHERE name = \'%s\'',
mysql_real_escape_string($_POST['nameQuery'])
);
Next up is what you asked for: a way to get both the users username and password. While I don't recommend that you actually store the password in plaintext for everyone to view, it's a decision you have to make on your own.
This snippet will do the deed:
<?php
//Get the data from the DB
$query = sprintf(
'SELECT * FROM myDatabase WHERE name = \'%s\'',
mysql_real_escape_string($_POST['nameQuery'])
);
$result = mysql_query($query);
$user_info = mysql_fetch_assoc($result);
//Check if it's valid
if( isset($user_info['name']) ) {
//Construct the message
$message = 'Your username is: ' . $user_info['name'] . "\n"
$message .= 'Your password is: ' . $user_info['password'] . "\n";
//Send it to the appropriate email
$status = mail(
$user_info['email'],
'Password recovery for ' . $user_info['name'],
$message
);
//Check if it actually worked
if( $status ) echo 'Mail sent. Check your inbox. Login again. Thank you.';
else echo 'The password recovery couldn\'nt be sent. Please try again later.';
} else {
echo 'No user found with the supplied username.',
'Please try again (with another username)';
}
?>
Edit: Adding password recovery-functionality
For the password recovery-functionality you requested below, you can try something like this:
recover_password.php:
<?php
session_start();
//mysql_connect()-here
//Initalize the variable
$do_update_password = false;
//Grab the token
$token = isset($_REQUEST['token'])? $_REQUEST['token'] : '';
$is_post_request = isset($_POST['update_pwd'])? true : false;
$is_recovery_request = isset($_POST['request_recovery'])? true : false;
$message = '';
//Check if we're supposed to act upon a token
if( $is_recovery_request ) {
//Grab the email
$email = isset($_POST['email'])? $_POST['email'] : '';
//Create the query, execute it and fetch the results
$sql = sprintf(
'SELECT `user_id` FROM myDatabase WHERE `email` = \'%s\'',
mysql_real_escape_string($email)
);
$result = mysql_query($sql);
$user_info = mysql_fetch_assoc($result);
//Validate the response
if( isset($user_info['user_id') ) {
//Let's generate a token
$date = date('Y-m-d H:i:s');
$token = md5($email . $date);
//Create the "request"
$sql = sprintf(
'INSERT INTO myRequests (`user_id`, `token`, `date`) VALUES (\'%s\', \'%s\', \'%s\')',
$user_info['user_id'],
mysql_real_escape_string($token),
$date
);
$result = mysql_query($sql);
//Validate
if( mysql_affected_rows($result) == 1 ) {
//Construct the message
$message = 'Your username is: ' . $user_info['email'] . "\n"
$message .= 'Please click on the following link to update your password: http://yoursite.com/request_password.php?token=' . $token . "\n";
//Send it to the appropriate email
$status = mail(
$email,
'Password recovery for ' . $email,
$message
);
//Check if it actually worked
if( $status ) {
echo 'Mail sent. Check your inbox. Login again. Thank you.';
} else {
echo 'The password recovery couldn\'nt be sent. Please try again later.';
}
} else {
$message = 'The DB-query failed. Sorry!';
}
} else {
$message = 'The specified e-mail address could not be found in the system.';
}
} elseif( $token != '' ) {
//Check so that the token is valid length-wise (32 characters ala md5)
if( !isset($token[31]) || !isset($token[32]) ) {
$message = 'Invalid token!';
} else {
//Construct the query and execute it
$sql = sprintf(
'SELECT `user_id` FROM myRequest WHERE `token` = \'%s\'',
mysql_real_escape_string($token);
);
$result = mysql_query($sql);
//Fetch the rows
$request_info = mysql_fetch_assoc($result);
//Check for a valid result
if( isset($request_info['user_id']) ) {
$message = 'Update your password below.';
$do_update_password = true;
} else {
$message = 'No record found for the following token: ' . $token);
}
}
} elseif( $is_post_request ) {
//Grab the new password
$password = isset($_POST['password'])? $_POST['password'] : '';
//Construct the query
$sql = sprintf(
'UPDATE myDatabase SET `password` = \'%s\' WHERE `user_id` = ( SELECT `user_id` FROM myRequest WHERE `token` = \'%s\' )',
mysql_real_escape_string($password),
mysql_real_escape_string($token)
);
//Execute it, and check the results
$result = mysql_query($sql);
if( $result !== false ) {
//Did we succeed?
if( mysql_affected_rows($result) === 1 ) {
//Remove the old recovery-request
$sql = sprintf(
'DELETE FROM myRequests WHERE `token` = \'%s\'',
mysql_real_escape_string($token)
);
$result = mysql_query($sql);
//^We don't actually need to validate it, but you can if you want to
$message = 'Password updated. Go have fun!';
} else {
$message = 'Could not update the password. Are you sure that the token is correct?';
}
} else {
$message = 'Error in the SQL-query. Please try again.';
}
}
?>
<!DOCTYPE html>
<html>
<head>
<title>Password recovery</title>
<style>
form > * { display: block; }
</style>
</head>
<body>
<h1><?php echo $message; ?></h1>
<?php if( $do_update_password ): ?>
<form method="post">
<label for="token">Token:</label>
<input type="text" name="token" id="token" value="<?php echo $token; ?>" />
<label for="password1">Password:</label>
<input type="text" name="password[]" id="password1" />
<label for="password2">Password (again):</label>
<input type="text" name="password[]" id="password2" />
<input type="submit" name="update_pwd" value="Update your password!" />
</form>
<?php elseif($is_post_request && $token != ''): ?>
<h2>Request that might've updated your password. Exciting!</h2>
<?php else: ?>
<form method="post">
<label for="email">E-mail address:</label>
<input type="text" name="email" id="email" />
<input type="submit" name="request_recovery" value="Request a new password" />
</form>
<?php endif; ?>
</body>
</html>
Note that I haven't had time to actually test the code, but I think it'll work just fine with some minor adjustments. Oh, before I forget, you'll need to add the following table to the DB:
Table structure for table myRequests
CREATE TABLE IF NOT EXISTS `myRequests` (
`request_id` int(6) NOT NULL AUTO_INCREMENT,
`token` varchar(32) NOT NULL,
`user_id` int(6) NOT NULL,
`date` datetime NOT NULL,
PRIMARY KEY (`request_id`),
UNIQUE KEY `token` (`token`,`user_id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;
Good luck!
While tangential to your original question, I would like to point out that storing passwords in plain text is a bad idea. You should store hashed versions of the password in the database. You can then hash user input and compare it to what is in the database for logging in.
Instead, your forgot password should create a new(temporary) password, and store the hash of that in the database, while sending the plain text password to the email account on file.
Just read the result:
/* ... */
if (mysql_num_rows($result) > 0) {
// User exists
$row = mysql_fetch_row($result);
print_r($row);
}
/* ... */
On a more general note: You have a SQL injection vulnerability in your code, please look into that topic, or attackers will be able to read all your user's passwords.
Also, it is not advised to store the password in clear text in you database. Please use a hashing algorithm like sha1 oder sha256 to store passwords.
I will recommend you to change your table design to
UserName
Password ' store hash
Password Retrieval Question ' store hash
Password Retrieval Answer ' store hash
When login check the user against the hashed password, something like this
$_POST['password']=sha1($_POST['password']);
When loggin in then use sql like
select col1,col2,.. from tbl where user=? and password=? and then fill the parameter with $_POST['username'], $_POST['password']
so use Prepared Statement or PDO
use the same logic when user forgot his password
<?php
session_start();
include "config.php";
if($_POST['nameQuery']) {
$query = "SELECT * FROM myDatabase WHERE name = '" .mysql_real_escape_string($_POST['nameQuery']). "'";
$result = mysql_query($query) or die ('Error: '.mysql_error());
if (mysql_num_rows($result) > 0) {
$row = mysql_fetch_assoc($result);
$message = 'Your password is: '.$row['password'];
if(mail($row['user_email'], 'Lost password', $message)){
echo 'Password sent';
}
} else {
echo 'Nu such user';
}
}
?>
You have to retrieve the username and password from the mysql_query result (stored in the $result variable) as such:
$row = mysql_fetch_array($result);
$username = $row['username'];
$password = $row['password'];
Then use php's mail() function to send the e-mail.

Categories