mySQLI - problem with mysqli_real_escape_string - php

I have this code, and works perfectly, but i want to make a simple modification
<?php session_start();
require 'includes/f_banco1.php';
require '../PasswordHash.php';
function checkBd($sql, $db, $user, $codePass) {
$user = $_GET['userid']; //here
$codePass = $_GET['code'];//here
if(is_numeric($user)) {
($sql = $db->prepare("select userid, code from password_reset where userid=? and code=?"));
$sql->bind_param('ss', $user, $codePass);
$sql->execute();
$sql->bind_result($user, $codePass);
if ($sql->fetch()) {
$_SESSION['u_name']= sha1($user);
header("location: updatePass.php");
return true;
}
else
echo "Não existe na BD";
return false;
}
else
echo "Erro";
}
checkBd ($sql, $db, $user, $codePass);
?>
i want to change these lines
$user = $_GET['userid']; //here
$codePass = $_GET['code'];//here
to
$user = mysqli_real_escape_string($db, $_GET['userid']);
$codePass = mysqli_real_escape_string($db, $_GET['code']);
but with this change the code simple stops work, an echo of $user doesn't show nothing
any idea?
thanks

You do not need to do that. You are using prepared statements, which escape the variables automatically.

If you prepare your statement, you don't need to escape your string.
Note: Your database connection must be opened to use mysqli_real_escape_string()

Related

Password_verify in PHP

So I'm enabling users to create accounts with a username and password. I have managed to encrypt the password when a user creates a new account using:
$hash = password_hash($password, PASSWORD_BCRYPT);
However I'm having trouble with password_verify when logging in, could someone please help me with what I have? I know it's something like this:
password_verify($password, $hash)
But I don't know how to structure it or where to add it in the code. Thanks in advance. This is what I have:
<?php
if (isset($_GET["username"]) && isset($_GET["password"]) ){
$username = $_GET["username"];
$password = $_GET["password"];
$result = login( $username, $password);
echo $result;
}
function makeSqlConnection()
{
$DB_HostName = "";
$DB_Name = "";
$DB_User = "";
$DB_Pass = "";
$con = mysql_connect($DB_HostName,$DB_User,$DB_Pass) or die(mysql_error());
mysql_select_db($DB_Name,$con) or die(mysql_error());
return $con;
}
function disconnectSqlConnection($con)
{
mysql_close($con);
}
function login($username, $password)
{
$con = makeSqlConnection();
$sql = "select * from login where username = '$username' and password = '$password';";
$res = mysql_query($sql,$con) or die(mysql_error());
$res1 = mysql_num_rows($res);
disconnectSqlConnection($con);
if ($res1 != 0) {
return 1;
}else{
return 0;
}// end else
}// end of Function
?>
The general practice is as follows:
Fetch password hash from the database where the username = the inputted username.
If rows are found, then there's a user
Now you compare the inputted password against the hash stored in the database.
I'll outline the above flow in some pseudo code for you here:
$query = SELECT password FROM users WHERE username = '$username'
$data = FETCH_THE_DATA($query);
if(password_verify($USER_INPUTTED_PASSWORD, $data['password'])) {
// password is correct
} else {
// password is in-correct
}
Notes
Stop using mysql_* functions. The library is deprecated as it's unreliable and will be removed in future releases of PHP.
You're better off using PDO or MySQLi Prepared Statements
You should always read the manual - password_verify(), it states clearly that you compare the "user inputted password" against the hashed version which is stored in your database.
Since I'm feeling good and sleepy today, I'll write a bunch of codes.
This is an example how to use PDO with prepared statement. You will have to tweak it according to your needs and you have to check if the post/get not empty as well.
I prefer to use POST request for login so this example will use POST request..
This is my user class. Which use placeholders and binding instead of passing the parameters into the query directly. This will give some protections against SQL injection attack.
class User{
private $dbh;
function __construct(){
$this->dbh = new PDO("mysql:host=".DB_SERVER.";dbname=".DB_NAME.';charset=utf8mb4', DB_USER, DB_PASSWORD) or die('db connect error');
}
function create($username, $password){
$status = false;
try{
$stmt = "INSERT INTO login (username, password)
VALUES (?, ?)";
$qry = $this->dbh->prepare($stmt);
$qry->bindParam(1, $username);
$qry->bindParam(2, $password);
$status = $qry->execute();
}catch(PDOException $e){
$e->getMessage();
}
$qry->closeCursor();
return $status;
}
public function getPassword($username){
$status = false;
try{
$stmt = "SELECT * FROM login WHERE username = ? LIMIT 1";
$qry = $this->dbh->prepare($stmt);
$qry->bindParam(1, $username);
$qry->execute();
$status = $qry->fetch(PDO::FETCH_ASSOC);
}catch(PDOException $e){
$e->getMessage();
}
$qry->closeCursor();
return $status;
}
}
This is how to create the user. Note that I don't check if the username already exist. You can either implement it yourself or use unique index on username column provided that the collation is case insensitive.
I have also increased the cost from the default that is 10 and I defined PASSWORD_DEFAULT to be used because I want the PHP engine to always use the strongest available algorithm (currently bcrypt).
function hashPassword($password){
$password = password_hash($password, PASSWORD_DEFAULT,array('cost' => 16));
return $password;
}
$user = new User;
$_POST['password'] = hashPassword($_POST['password']);
if(!$user->create(trim($_POST['username']),$_POST['password'])){
echo 'Failed creating user';
}else{
echo 'User created';
}
This is how to verify the password.
$user = new User;
$getPassword = $user->getPassword(trim($_POST['username']));
if(!$getPassword){
echo 'Error fetching user';
}else{
if(!password_verify($_POST['password'], $getPassword['password'])){
echo 'Login failed';
}else{
echo 'Login successful';
}
}

PHP Error: call to a member function bind_param() on a non-object

I have a php script which should connect to a database, check whether a row with the given field exists and, if it exists, update another field of the same row. However, the UPDATE query seems to fail, and I can't see why. I tried to google the problem but couldn't find a working solution. I tried to echo($mysqli->error) but it gave me an empty string.
Here's the code:
<?php
session_start();
include "../config.php";
if(isset($_GET['actionForgot']) && !empty($_GET['restore'])) {
$piva=trim($_GET['restore']);
$mysqli = new mysqlc();
$stmt = $mysqli->prepare("SELECT username,email FROM login WHERE piva = ?");
$stmt->bind_param("s", $piva);
if (!$stmt->execute()) {
trigger_error('The query execution failed; MySQL said ('.$stmt->errno.') '.$stmt->error, E_USER_ERROR);
}
$stmt->bind_result($username, $email);
if($stmt->fetch()) {
$password = generatePassword(10);
$crypPass = MD5($password);
$stmt = $mysqli->prepare("UPDATE login SET password = ? WHERE piva = ?"); //Here's the error!
if(!$stmt->bind_param("ss",$crypPass,$piva)){
echo "fail";
} else if (!$stmt->execute()) {
trigger_error('The query execution failed; MySQL said ('.$stmt->errno.') '.$stmt->error, E_USER_ERROR);
echo "fail";
} else {
sendEmailRestore($username, $password, $email);
echo $email;
}
} else {
echo "nexists";
}
$stmt->close();
}else{
echo "false";
}
?>
P.S. I'm sure the problem is not in config.php because other similar php scripts work just fine.
EDIT: Could it have something to do with the fact I'm using the same variable $stmt for two queries?
I've found the problem! It had something to do with $mysqli being used for two different queries. I have no idea why this should give problems of any kind, but I changed the code to this:
<?php
session_start();
include "../config.php";
if(isset($_GET['actionForgot']) && !empty($_GET['restore'])) {
$piva=trim($_GET['restore']);
$mysqli = new mysqlc();
$stmt = $mysqli->prepare("SELECT username,email FROM login WHERE piva = ?");
$stmt->bind_param("s", $piva);
if (!$stmt->execute()) {
trigger_error('The query execution failed; MySQL said ('.$stmt->errno.') '.$stmt->error, E_USER_ERROR);
}
$stmt->bind_result($username, $email);
if($stmt->fetch()) {
$password = generatePassword(10);
$crypPass = MD5($password);
$mysqli2 = new mysqlc(); //NOTICE THIS LINE
$stmt = $mysqli2->prepare("UPDATE login SET password = ? WHERE piva = ?"); //AND THIS
if(!$stmt->bind_param("ss",$crypPass,$piva)){
echo "fail";
} else if (!$stmt->execute()) {
trigger_error('The query execution failed; MySQL said ('.$stmt->errno.') '.$stmt->error, E_USER_ERROR);
echo "fail";
} else {
sendEmailRestore($username, $password, $email);
echo $email;
}
} else {
echo "nexists";
}
$stmt->close();
}else{
echo "false";
}
?>
and it works just fine.
I'd still like to know why I was doing it wrong, though...

Having trouble logging a user in using PHP and PDO

From the PDO manual:
PDOStatement::rowCount() returns the number of rows affected by the last DELETE, INSERT, or UPDATE statement executed by the corresponding PDOStatement object.
If the last SQL statement executed by the associated PDOStatement was a SELECT statement, some databases may return the number of rows returned by that statement. However, this behaviour is not guaranteed for all databases and should not be relied on for portable applications.
I have this code:
<?php
require 'core.inc.php';
if(isset($_POST['user']) AND isset($_POST['pass'])){
if(!empty($_POST['user']) AND !empty($_POST['pass'])){
$user = $_POST['user'];
$pass = $_POST['pass'];
require 'connect.inc.php';
$st = $db_pdo->prepare("SELECT id FROM users WHERE user=? AND pass=?");
$st->bindParam(1, $user);
$st->bindParam(2, $pass);
$st->execute();
$result = $st->fetchColumn();
if($st->rowCount() > 0){
$id_arr = $st->fetch();
$id = $id_arr[0];
$_SESSION['user_id'] = $id;
header('Location: edit.php');
} else { echo 'Username or password incorrect';}
} else { echo 'You must fill in all fields.';}
}
?>
The number of rows returned is always 0, as stated in the manual. No surprise there.
1) I want to log a user in and set his $_SESSION id to his user ID from a db.
2) I suck so much at PDO it's not even funny, I can't figure out what function to use to log the user in. If the number or rows is always 0, clearly the Username or password incorrect will appear all the time.
Try this :
try
{
$pdo_options[PDO::ATTR_ERRMODE] = PDO::ERRMODE_EXCEPTION;
$bdd = new PDO('mysql:host='.$host.';dbname=' . $dbname, $dbuser, $dbpassword, $pdo_options);
$request = $bdd->prepare('SELECT id FROM users WHERE user = :user AND pass = :password');
$request->execute(array('user' => $_POST['user'],
'password' => $_POST['pass']
));
$data = $request->fetch();
if ($data)
{
session_start();
$_SESSION['ID'] = $data['id'];
//you can run other verification here if you want
header('Location: edit.php');
}
else
{
echo 'Username or password incorrect';
}
$requete->closeCursor();
}
catch(Exception $erreur)
{
die('Login error : '.$erreur->getMessage());
}
Hope that helps .

MySQLi Num Rows Doesnt Work

i have a simple login system and i get nothing when trying to fetch the number of rows, the same method used to work all the time, i dont know what is going on today.
Code:
<?php
class LoginClass {
public $User;
public $Pass;
public $Query;
function Init() {
$User = $this->User;
$Pass = $this->Pass;
if($User != '')
{
if($Pass != '')
{
$this->HashPass();
}
else
{
echo 'Please Enter A Password.';
}
}
else
{
echo 'Please Enter A Username or E-Mail.';
}
}
function HashPass() {
$Pass = $this->Pass;
$this->Pass = hash('sha256', $Pass);
$this->CheckUser();
}
function CheckUser() {
$User = $this->User;
if(!filter_var($User, FILTER_VALIDATE_EMAIL))
{
$this->Query = 'SELECT * FROM Users WHERE User = "'.$User.'" AND Pass = "'.$this->Pass.'"';
}
else
{
$this->Query = 'SELECT * FROM Users WHERE EMail = "'.$User.'" AND Pass = "'.$this->Pass.'"';
}
$this->CheckDB();
}
function CheckDB() {
$Query = $this->Query;
$Connect = new mysqli("127.0.0.1", "root", "", "Data");
$Stmt = $Connect->prepare($Query)
$Stmt->execute();
$Stmt->store_result();
echo $Stmt->num_rows;
$Stmt->close();
$Connect->close();
}
function SetupSession() {
echo 'Test';
}
}
the Check DB is the problem here and im able to echo out the query variable in that function everything is fine, here is exactly what i get
SELECT * FROM Users WHERE User = "Test" AND Pass = "532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e25"
I also checked my DB and all my tables are setup correctly and there is no password.
OK, need more space than the comments area, the issue is clearly in this block:
function CheckDB() {
$Query = $this->Query;
$Connect = new mysqli("127.0.0.1", "root", "", "Data");
$Stmt = $Connect->prepare($Query)
$Stmt->execute();
$Stmt->store_result();
echo $Stmt->num_rows;
$Stmt->close();
$Connect->close();
}
I think it's because you aren't binding parameters to the prepared statement, you've already included them inline in your earlier statement. Therefore, you probably want to:
Switch to non-prepared statement
The easy option here will be to switch to a non-prepared statement. Replace your block with:
function CheckDB() {
$Query = $this->Query;
$Connect = new mysqli("127.0.0.1", "root", "", "Data");
$Stmt = $Connect->query($Query)
echo $Stmt->num_rows;
$Stmt->close();
$Connect->close();
}
A word of caution with this approach: you need to sanitize your user input in the block which defines $User, otherwise you're leaving yourself open to mysql injection. In that block, change this line:
$User = $this->User;
To the following:
$User = mysql_real_escape_string($this->User);

How to successfully rewrite old mysql-php code with deprecated mysql_* functions? Part II

Continuing from this topic where we explained most problems with PDO How to successfully rewrite old mysql-php code with deprecated mysql_* functions? now about understanding prepared statements... So in order to get remove mysql_* strings there are some examples so my question for all and other users may this find helpfull which solution is the best ... so example of old "made up* code:
in config.php:
$db = new dbConn('127.0.0.1', 'root', 'pass', 'people', 'login');
in login.php
$db->selectDb("login");
$query = mysql_query("SELECT * FROM account WHERE id='".$_session["id"]."' LIMIT 1");
$result = mysql_fetch_array($query);
$_session["id"] is defined when login actually, so now we have several options to do so:
In config.php:
$db_people = new PDO('mysql:host=127.0.0.1;dbname=people;charset=UTF-8', 'root', 'pass');
$db_login = new PDO('mysql:host=127.0.0.1;dbname=login;charset=UTF-8', 'root', 'pass');
And in login.php 1):
$stmt = $db_login->prepare("SELECT * FROM account WHERE id=? LIMIT 1");
$stmt->execute(array($_session["id"]));
$results = $stmt->fetchAll(PDO::FETCH_ASSOC);
Or this one is better when exclude query? Or the previous one is better?
And in login.php 2):
$query = "SELECT * FROM account WHERE id=? LIMIT 1";
$parameters = array($_session["id"]);
$statement = $db_login->prepare($query);
$statement->execute($parameters);
$results = $statement->fetch(PDO::FETCH_ASSOC);
And this login form:
public function login($user, $password)
{
global $web, $db;
if (!empty($user) && !empty($password))
{
$user = $web->esc($user);
$password = $web->doHash($user, $password);
$db->selectDb('login');
$qw = mysql_query("SELECT * FROM account WHERE username='".$user."' AND pass_hash='".$password."'");
if (mysql_num_rows($qw) > 0)
{
$result = mysql_fetch_array($qw);
$_session['name'] = $result['username'];
$_session['id'] = $result['id'];
return true;
}
else
return false;
}
else
return false;
}
Transfered into this form:
public function login($user, $password)
{
global $web, $db_login;
if (!empty($user) && !empty($password))
{
$user = $web->esc($user);
$password = $web->doHash($user, $password);
$stmt = $db_login->prepare("SELECT * FROM account WHERE username=? AND pass_hash=?");
$stmt->execute(array($user, $password));
$rows = $stmt->rowCount();
if ($rows > 0)
{
$result = $stmt->fetchAll(PDO::FETCH_ASSOC);
$_session['name'] = $result['username'];
$_session['id'] = $result['id'];
return true;
}
else
return false;
}
else
return false;
}
Is it ok or again do separate query or maybe do it in complete different way? Thank you all.
Also when there is multiple stmt should I use different name for it? For example I use stmt once and make a result1 after I do stmt second with result2 should I choose different name also for stmt variable or only result name is ok to be different?
OK so solution login.php 1) seems to be ok simple and no rush.
Also the login page seems to be working fine and therefore it should be according to every rules and ok :)

Categories