I get an error on the last line on mysqli_escape_string($hash));
by using the following code:
$hash = md5( rand(0,1000) );
$stmt = $mysqli->prepare("INSERT INTO users (username, password, hash) VALUES (?, ?, mysqli_escape_string($hash))");
$password = md5($password);
$stmt->bind_param('ss', $username, $password, mysqli_escape_string($hash));
It says, that the mysqli_escape_string($hash))
is a non-object.
But using only $hash
instead doesn't help either
Can someone help?
There are far too many things wrong with your code and will be extremely difficult to provide a solution by fixing what you have now.
Firstly, MD5 is no longer considered safe to use for password storage.
Consult:
- https://security.stackexchange.com/questions/19906/is-md5-considered-insecure
- https://en.wikipedia.org/wiki/MD5
Plus, you're not using prepared statements correctly.
- Consult: http://php.net/manual/en/mysqli.prepare.php
As I stated, the mysqli_escape_string()
function requires a database connection be passed as the first parameter:
- http://php.net/manual/en/mysqli.real-escape-string.php
Do yourself a favor and use this, one of ircmaxell's answers https://stackoverflow.com/a/29778421/
Pulled from his answer:
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
}
Your code should be
$hash = md5( rand(0,1000) );
$stmt = $mysqli->prepare("INSERT INTO users (username, password, hash) VALUES (?, ?, ?)");
$password = md5($password);
$stmt->bind_param('sss', $username, $password, $hash);
You don't need to escape with parameterized queries.
Issues you had, your escape
function was incorrect you need the object with the function when using OO approach.
$mysqli->real_escape_string($hash);
would have been what you wanted.
You also were binding that value again though which would have thrown an error and didn't set it in the variable types being passed.
A string that contains one or more characters which specify the types for the corresponding bind variables.
So
$stmt->bind_param('ss', $username, $password, mysqli_escape_string($hash));
should have had three 's's because there are three strings, and no need for the escaping.
Also md5
ing passwords isn't the best practice anymore, take a look at:
Secure hash and salt for PHP passwords
https://security.stackexchange.com/questions/19906/is-md5-considered-insecure