Having searched thoroughly through my code, the only reason that I could determine for this error is that the technique I am using for converting the string to MD5 is invalid. However I cannot find another way to do so.
$username = $_POST['username'];
$password = $_POST['password'];
$repassword = $_POST['repassword'];
if( $password=$repassword ) {
$con=mysql_connect("localhost", "root", "");
if( $con == true ) {
mysql_select_db("movedb", $con);
//$newpassword = mysql_real_escape_string(md5($_POST['password']));
$query = "UPDATE user SET password=MD5('$password') WHERE username='$username'";
// $query = "UPDATE user SET password='$newpassword' WHERE username='$username'";
$result = mysql_query($query, $con);
if( $result == true ) {
echo "Successfully saved your message";
} else {
echo mysql_error();
}
mysql_close($con);
} else {
echo "Cannot connect to the database";
}
} else {
echo "Passwords do not match!";
}
Any ideas on how to update this MD5 value from PHP
$password = md5($password);
$query = "UPDATE user SET password='".$password."' WHERE username='".$username."'";
Use PHP supported md5 hash.
An issue that can cause problems is that MySQL and PHP use different default salts when they encrypt. This means that the resulting strings will be different. So you have to use either PHP or MySQL to encrypt and not a mixture of the 2.
Secondly, MD5 has been superceded by other better encryption algorithms. You might consider using one of those for improved security. Check out PHP's crypt() function.
To check the password:
SELECT * FROM 'user' WHERE username='bob.jhonny' AND pass=MD5('oldPassword');
To update:
UPDATE 'dlp_contatcs'.'user' SET 'Pass'=MD5('NewPassword') WHERE 'Username'='bob.jhonny';
Warning:
Please, don't use mysql_* functions to write new code. They are no longer maintained and the community has begun the deprecation process. See the red box?
Instead, you should learn about prepared statements and use either PDO or MySQLi. This article should give some details about deciding which API to use. For PDO, here is a good tutorial.
You can calculate the md5() hash with PHP and store it into a variable, then put that variable into the database. Just make sure you do the same conversion (md5 in the PHP code body) when checking against the database.
You should fix the line if( $password=$repassword ). You need either two or three = signs to make the if check against something. The proper line would be if( $password === $repassword ).
// ...
$newpassword = md5($_POST['password']);
$result = mysql_query('UPDATE user SET password="' .mysql_real_escape_string($newpassword). '" WHERE username = "' .mysql_real_escape_string($username). '"', $con);
if ( $result === TRUE )
{
echo "Successfully saved your message.";
// ...
Related
I set up a dev server and I installed nginx with php-fpm and 7.2 php (I installed all the necessary php packages).
The time has come to upgrade the security of all logins, using the argon2i algo.
So, I tried this (test code in dev enviroment. The security in the code, will come later):
require('connector.php');
$usr_u = $_POST['username'];
$psw_u = $_POST['password'];
$usr = mysqli_real_escape_string($conn, $usr_u);
$psw = mysqli_real_escape_string($conn, $psw_u);
$f_pass = password_hash($psw, PASSWORD_ARGON2I);
$result = "SELECT `username` FROM `users` WHERE username = '$usr'";
$tbl = mysqli_query($conn, $result);
$table = $tbl->fetch_assoc();
$m_user = $table['username'];
if ($m_user == $usr)
{
//correct username
echo 'Correct username!<br>';
$result = "SELECT `password` FROM `users` WHERE username = '$m_user'";
$tbl = mysqli_query($conn, $result);
$table = $tbl->fetch_assoc();
$m_pass = $table['password'];
if (password_verify($m_pass,$f_pass)) //always returns false
{
echo 'Password correct!<br>';
}
else
{
echo 'Wrong password!<br>';
}
}
else
{
echo 'Wrong username!<br>';
}
//close connection
mysqli_close($conn);
I always get "Correct username!" and "Wrong password!". I used echo on hashed password from the DB and from the input and I see that every time the hashed password is different. I assume that the hashing process, include using random salt and there is my issue.
As far as I understand, the random salt is necessary in order to retain the security of the hashing.
Can you please point me to the right direction, on how to solve this? I have the hashed password in my DB and I can't figure out a way to check the input password against the one in my DB (using password_verify and hash_equals).
Thank everyone in advance for the help.
Look at the documentation for password_verify:
bool password_verify ( string $password , string $hash )
The first argument is the password but you are passing it the hash you want to compare it to.
The second argument is the hash you want to compare it to but you are passing it a new hash created from user input.
password_verify($_POST['password'], $m_pass)
So I just learned about storing passwords with MD5 hash and salt in PHP/MySQL. The method I'm using is md5(md5($row["id"].$password)), so the salt is an MD5 hash of the user's ID in my SQL table (which is an auto-incremented INT), which is concatenated to the inputted password string and then re-hashed.
The problem I'm encountering is that when I trying making a test account, and then logging in with the test account, the hash I generate on logging in isn't matching the hash I created when the account was created.
Login Code:
<?php
$login = mysqli_connect("hiding this info for obvious reasons");
if ($_POST["login"])
{
$email = $_POST["email"];
$password = $_POST["passsword"];
$query = "SELECT * FROM useraccs WHERE email='$email'";
if ($result = mysqli_fetch_array(mysqli_query($login,$query)))
{
$hashpass = md5(md5($result["id"]).$password);
if ($hashpass == $result["password"])
{
$errors = "Logged in succesfully.";
}
}
else
{
$error.= "E-mail/Password do not match anything in our database.";
}
}
?>
Register Code:
<?php
$login = mysqli_connect("hiding this info for obvious reasons");
if ($_POST["submit"])
{
$username = $_POST["username"];
$email = $_POST["email"];
$query = "INSERT INTO useraccs (username,email) values('$username','$email')";
mysqli_query($login,$query);
$query = "SELECT id FROM useraccs WHERE username='$username'";
$userid = mysqli_fetch_array(mysqli_query($login,$query))["id"];
$password = md5(md5($userid).$_POST["password"]);
$query = "UPDATE useraccs SET password='$password' WHERE username='$username'";
mysqli_query($login,$query);
}
?>
As you can see, the way I hash the password in both scenarios is identical, and I have done testing to confirm that I am getting the same value for the ID in both scenarios. I am truly stumped as to why I am not getting a match.
I'd like to mention I am very new to using MySQL/creating login systems, so if I've done anything blatantly wrong or have left out essential information, please let me know.
First of all, please see the warnings in the comments, your code is highly unsure.
Regarding the md5: You are using
mysqli_fetch_array(mysqli_query($login,$query))["id"];
This will always return an array. Be sure to get only the field.
I hope I formatted the code properly. I am having trouble making this if statement to work. I've searched and from what it looks like this statement should work. However, when I run it no matter the password if the username starts with kacey then it goes to echo "Logged in as: " . kacey;
Likewise, if I put the input to kaceyfeewaf, it still goes to echo "Logged in as: " . $myuser; This happens regardless of the password I put in. the line $result['username'] should validate to KACEY.
$sql = "SELECT * FROM $dbTable WHERE username = $myuser AND password = $mypass";
$result = mysql_query($sql);
if($result['username'] = $myuser && $result['password'] = $mypass;)
{
echo "Logged in as: " . $myuser;
} else {
echo "Fail ";
}
There are a few issues here.
Firstly, the variables you have in your query are strings, therefore they require to be quoted:
WHERE username = '$myuser' AND password = '$mypass'
Having or die(mysql_error()) to mysql_query() would have signaled the syntax error.
Then you're assigning instead of comparing with
if($result['username'] = $myuser && $result['password'] = $mypass;)
use two equals ==
However, that isn't how you check if those rows exist.
You need to use mysql_num_rows() or use a while loop while using a function to fetch/iterate over results found.
Here is an MySQLi example using mysqli_num_rows():
$conn=mysqli_connect("hostname","username","password","db");
$check_select = mysqli_query($conn, "SELECT * FROM `users`
WHERE email = '$email' AND pw='$pass'");
$numrows=mysqli_num_rows($check_select);
if($numrows > 0){
// do something
}
Now, we don't know where those variables have been assigned, and if from a form that it's using a POST method with matching name attributes.
I.e.:
<form action="" method="post">
<input type="text" name="username">
...
</form>
$username = $_POST['username'];
Another thing which is unknown to us is the MySQL API you're using to connect with. Make sure that you are indeed using the same one as you are using to query with, being mysql_. Different APIs do not intermix, such as mysqli_ or PDO. Use the same one from connection to querying.
Add error reporting to the top of your file(s) which will help find errors.
<?php
error_reporting(E_ALL);
ini_set('display_errors', 1);
// rest of your code
Sidenote: Displaying errors should only be done in staging, and never production.
I noticed you may be storing passwords in plain text. If this is the case, it is highly discouraged.
I recommend you use CRYPT_BLOWFISH or PHP 5.5's password_hash() function. For PHP < 5.5 use the password_hash() compatibility pack.
Here is a PDO solution pulled from one of ircmaxell's answers:
https://stackoverflow.com/a/29778421/
Just use a library. Seriously. They exist for a reason.
PHP 5.5+: use password_hash()
PHP 5.3.7+: use password-compat (a compatibility pack for above)
All others: use phpass
Don't do it yourself. If you're creating your own salt, YOU'RE DOING IT WRONG. You should be using a library that handles that for you.
$dbh = new PDO(...);
$username = $_POST["username"];
$email = $_POST["email"];
$password = $_POST["password"];
$hash = password_hash($password, PASSWORD_DEFAULT);
$stmt = $dbh->prepare("insert into users set username=?, email=?, password=?");
$stmt->execute([$username, $email, $hash]);
And on login:
$sql = "SELECT * FROM users WHERE username = ?";
$stmt = $dbh->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
}
You should use == instead of simple = for your if condition
First of all delete that if stmt and make new one where you check for num rows. If there is num rows > 0 you have valid login. And then print needed results from database od current query.
Edit:
You have = insted of == or === so stmt is always true.
I'm kinda new to the OOP(? If this IS OOP, I don't know) language, and I'm trying to make a simple login-proccess, with MySQLi. The problem are, that the code doesn't work. I can't login (and It's not showing me any errors) and I can't register an new account (same problem) - It's like the code are dead or something.
I'm not sure I've done it right, but this is my best, so far. 'cause I'm new to OOP(?).
Index.php:
<?php
if(isset($_POST['submit'])) {
$username = mysql_real_escape_string($_POST['username']);
$password = mysql_real_escape_string(md5($_POST['password']));
$userControl = "SELECT * FROM users WHERE username='".$username."' AND password='".$password."'";
$userControlResult = $mysqli->query($userControl);
if($mysqli->num_rows($userControlResult) > 1) {
$userRow = $mysqli->fetch_assoc($userControlResult);
$dbid = $userRow['id'];
$dbuser = $userRow['username'];
$_SESSION['id'] = $dbid;
$_SESSION['username'] = $dbuser;
header("location: me.php");
die();
} else {
echo "<div class='errorField'>Användarnamnet eller lösenordet är fel!</div>";
}
}
?>
I suppose that if I can solve the first error, I can solve the second too.
Thanks!
Many things I would recommend changing about your code:
Don't use mysql_real_escape_string() if you're using mysqli. You can't mix these APIs.
No need to escape a string returned by md5(), because it's guaranteed to contain only hexadecimal digits.
Don't use mysqli_real_escape_string() anyway -- use parameters instead.
Always check if prepare() or execute() return false; if they do, then report the errors and exit.
You can get a mysqli result from a prepared statement using mysqli_stmt_store_result().
Don't SELECT * if you don't need all the columns. In this case, you already have $username so all you really need to fetch is the id column.
No need to check the number of rows returned, just start a loop fetching the rows (if any). Since you exit inside the loop, your "else" error clause will be output only if the loop fetches zero rows.
Consider using a stronger password hashing function than MD5. Also, add a salt to the password before hashing. Read You're Probably Storing Passwords Incorrectly.
Example:
<?php
if(isset($_POST['submit'])) {
$username = $_POST['username'];
$password = md5($_POST['password']);
$userControl = "SELECT id FROM users WHERE username=? AND password=?";
if (($userControlStmt = $mysqli->prepare($userControl)) === false) {
trigger_error($mysqli->error, E_USER_ERROR);
die();
}
$userControlStmt->bind_param("ss", $username, $password);
if ($userControlStmt->execute() === false) {
trigger_error($userControlStmt->error, E_USER_ERROR);
die();
}
$userControlResult = $userControlStmt->store_result();
while($userRow = $userControlResult->fetch_assoc()) {
$_SESSION['userid'] = $userRow["id"];
$_SESSION['username'] = $username;
header("location: me.php");
die();
}
// this line will be reached only if the while loops over zero rows
echo "<div class='errorField'>Användarnamnet eller lösenordet är fel!</div>";
}
?>
A good command to enter at the top of the script (under the
ini_set('display_errors', 1);
This will display any errors on your script without needing to update the php.ini (in many cases). If you try this, and need more help, please post the error message here and I'll be able to help more.
Also, if you are using $_SESSION, you should have
session_start();
at the top of the script under the
Make sure your php is set to show errors in the php.ini file. You'll need to do some research on this on your own, but it's fairly easy to do. That way, you'll be able to see what the error is and go from there.
Is there a way to make the username part work for both upper and lower case, for example if my username were robert if you entered Robert it would work as well? Attached is a copy of my login script.
<?php
session_start();
$username = $_POST['username'];
$password = $_POST['password'];
if ($username&&$password)
{
$connect = mysql_connect("localhost","*i*****5_******","*******") or die ("Couldn't Connect"); //host,username,password
mysql_select_db("virtua15_gateway") or die ("Could not find database");
$query = mysql_query("SELECT * FROM Users WHERE username='$username'");
$numrows = mysql_num_rows($query);
if ($numrows!=0)
{
while ($row = mysql_fetch_assoc($query))
{
$dbusername = $row['username'];
$dbpassword = $row['password'];
}
if ($username==$dbusername&&md5($password)==$dbpassword)
{
header( 'Location: index2.php' );
$_SESSION['username']=$dbusername;
}
else
echo "incorrect username and password";
}
else
die ("This user does not exist");
}
else
die("Please enter a username and a password")
?>
check strtolower($username) == strtolower($dbusername)
I'm a bit confused why you're checking it twice though. You've already checked in your sql query if the usernames match. Also, are your username's not unique? Why are you doing a while loop and not just a if (false !== ($row = mysql_fetch_assoc($query)) {}
Also, you should make sure your $dbusername and $dbpassword get defined because if a row is not found, they won't be, and PHP will issue a warning about undefined variables when you access them.
Also, you should be checking if the $_POST keys are set. I tend to code a bit paranoid, but I like to make notices/warning very hard to get. If your server were set to display errors, a user could see either a rather ugly error message, or potentially even sensitive data.
Also, while I'm being way overly picky, as per the HTTP specification, the Location header expects a full URL, not just a relative file name (though all browsers support just a relative file name).
Convert to either lower/upper case or make a case insensitive match.
Important
Please don't do this:
$username = $_POST['username'];
$query = mysql_query("SELECT * FROM Users WHERE username='$username'");
As it will allow hackers to perform SQL injection! Please sanitise ALL of your inputs!
IE,
$username = mysql_real_escape_string($_POST['username']);
$password = mysql_real_escape_string($_POST['password']);
Important
Edit :: Also, NEVER use PHP to do the job of php
$query = mysql_query("SELECT * FROM Users WHERE username='$username'");
Is wrong, you should perform the sql query with your login logic!
IE
"SELECT * FROM Users WHERE username='$username' AND password='" . md5($password) . '"
Then you can just say this instead
if(mysql_num_rows($query)){
// Login logic
}
Edit ::
SQL queries are case insensitive
hi try strtolower() function.
$username = strtolower($_POST['username']);
Check this http://php.net/manual/en/function.strtolower.php
You can check by two tyes:
while ($row = mysql_fetch_assoc($query))
{
strtoupper($dbusername) = strtoupper($row['username']);
$dbpassword = $row['password'];
}
OR
while ($row = mysql_fetch_assoc($query))
{
strtolower($dbusername) = strtolower($row['username']);
$dbpassword = $row['password'];
}
Use any one of them.
this will resolve your problem.
A working alternative in MySQL:
mysql_query(
"SELECT * FROM Users
WHERE LOWER( username) = LOWER( '" . mysql_real_escape_string( $username) . "')"
);
If your requirement is to allow login irrespective of the case , I mean Robert, robert, ROBERT, RoBeRT etc.. , then you can consider storing the username in lowercase in the database and while retrieving convert the username to lowercase and execute the query