password_verify having a few issues hopefully someone can help me - php

So im making a login for a game system that uses a JSON string to read back the files, however when I Hash the password and try login it doesn't work however when the password is unhased it works fine, I think the problem lies with the password verify part.
Im just unsure where to place it if someone could guide me in the right direction that will be amazing...
So the issue is when I send the $password example test5 it only reads as test 5 and not this $2y$10$viov5WbMukXsCAfIJUTUZetGrhKE9rXW.mAH5F7m1iYGfxyQzQwD.
This was the original Code
<?php
include("dbconnect.php");
/////// First Function To Get User Data For Login
if($_GET["stuff"]=="login"){
$mysqli = new mysqli($DB_host, $DB_user, $DB_pass, $DB_name);
if (mysqli_connect_errno()) {
printf("Connect failed: %s\n", mysqli_connect_error());
exit();
}
/////// Need to Grab Username And Password
$username = $_GET["user"];
$password = $_GET["password"];
$query = "SELECT username, password, regkey, banned FROM users WHERE username='$username' and password='$password'";
if ($stmt = $mysqli->prepare($query)) {
$stmt->execute();
$stmt->bind_result($username, $password, $regkey, $banned);
while ($stmt->fetch()) {
echo "{";
echo '"result": "success",';
echo '"regkey": "' . $regkey . '",';
echo '"banned": "' . $banned . '"';
echo "}";
}
$stmt->close();
}
$mysqli->close();
}
Then I tried This
<?php
include("dbconnect.php");
/////// First Function To Get User Data For Login
if($_GET["stuff"]=="login"){
$mysqli = new mysqli($DB_host, $DB_user, $DB_pass, $DB_name);
if (mysqli_connect_errno()) {
printf("Connect failed: %s\n", mysqli_connect_error());
exit();
}
/////// Need to Grab Username And Password
$username = $_GET["user"];
$password = $_GET["password"];
$GetPassword = "SELECT password FROM users WHERE username='$username'";
$data = mysqli_query($GetPassword);
if(password_verify($password, $data['password'])) {
$query = "SELECT username, password, regkey, banned FROM users WHERE username='$username' and password='$password'";
if ($stmt = $mysqli->prepare($query)) {
$stmt->execute();
$stmt->bind_result($username, $password, $regkey, $banned);
while ($stmt->fetch()) {
echo "{";
echo '"result": "success",';
echo '"regkey": "' . $regkey . '",';
echo '"banned": "' . $banned . '"';
echo "}";
}
$stmt->close();
}
} else {
// password is in-correct
}
$mysqli->close();
}

$data = mysqli_query($GetPassword);
^^^---mysqli result handle/object
if(password_verify($password, $data['password'])) {
^^^^^^^^^^^^---no such element in mysqli
You never fetched your data results, so you're comparing the entered password against a non-existent element of the $data result object/handle.
You need
$row = mysqli_fetch_assoc($data);
password_verify(..., $row['password']);
Most likely you're running with error_reporting and display_errors disabled, meaning you'd never see the "undefined index" warnings that PHP would ave been throwing everytime you ran this code. Those settings should NEVER be off on a devel/debug system.
And note that you're vulnerable to sql injection attacks, so your "security" system is anything but -it's entirely useless and trivially bypassable.

There are several issues with your code, such as:
This statement $data = mysqli_query($GetPassword) is wrong. mysqli_query() expects first argument to be your connection handler, so it should be,
$data = mysqli_query($mysqli, $GetPassword);
Look at this statement, if(password_verify($password, $data['password'])) { ...
mysqli_query(), on success, returns a result set, so you can't get the password using $data['password']. First fetch the row from the result set and then get the password, like this,
$row = mysqli_fetch_assoc($data);
if(password_verify($password, $row['password'])) { ...
Look at the following query,
$query = "SELECT username, password, regkey, banned FROM users WHERE username='$username' and password='$password'";
This query won't return any rows because of this WHERE condition, ...password='$password'. So the solution is, instead using two separate queries, use only one query to validate the password and retrieve relevant data. The solution is given down below.
Your queries are susceptible to SQL injection. Always prepare, bind and execute your queries to prevent any kind of SQL injection.
If you want to build a json string then instead of doing echo "{"; echo '"result": "success",'; ..., create an array comprising of all the relevant data and then json_encode the array.
So the solution would be like this:
// your code
$username = $_GET["user"];
$password = $_GET["password"];
// create a prepared statement
$stmt = mysqli_prepare($mysqli, "SELECT username, password, regkey, banned FROM users WHERE username=?");
// bind parameters
mysqli_stmt_bind_param($stmt, 's', $username);
// execute query
mysqli_stmt_execute($stmt);
// store result
mysqli_stmt_store_result($stmt);
// check whether the SELECT query returned any row or not
if(mysqli_stmt_num_rows($stmt)){
// bind result variables
mysqli_stmt_bind_result($stmt, $username, $hashed_password, $regkey, $banned);
// fetch value
mysqli_stmt_fetch($stmt);
if(password_verify($password, $hashed_password)){
echo json_encode(array('result' => 'success', 'regkey' => $regkey, 'banned' => $banned));
}else{
// incorrect password
}
}else{
// no results found
}
mysqli_stmt_close($stmt);
// your code

Related

PHP inserting with bind_param

I am currently working trying to use the statements mysqli_prepare and bind_param in order to pass arguements more safely into my query. I was doing mysqli_query to execute them before which worked fine. My professor is requiring us to use prepare though. I currently am getting the proper values from my form but the data isn't being entered into customer table. Also, I have mysqli_error() on my execute() commands but I am not getting any errors at all which is making debugging difficult. Here is the php part located in register.php
<?php
require 'connection.php';
$result = "";
if(isset($_POST['register'])) {
#Fetch the data from the fields
$username = $_POST['username'];
$password = $_POST['password'];
$name = $_POST['name'];
$total = 0.0;
#echo $username . " " . $password . " " . $name . " " . $total;
#Prepare sql query to see if account already exists
$query = mysqli_prepare("SELECT * FROM customer WHERE username=?");
$query->bind_param("s", $username);
$query->execute() or die(mysqli_error());
if(mysqli_num_rows($query) > 0) {
#This username already exists in db
$result = "Username already exists";
} else {
$insert = mysqli_prepare("INSERT INTO customer(username, password, name, total) VALUES (?, ?, ?, ?)");
$insert->bind_param("sssd", $username, $password, $name, $total);
$insert->execute() or die(mysqli_error());
#$result = "Account registered!"
}
}
?>
I establish connection to my db like this in connection.php
$conn = new mysqli(DB_HOST, DB_USERNAME, DB_PASSWORD, DB_DATABASE);
Like I said before, I can get the query to execute with mysqli_query but for some reason I cannot get param to work. Also tried adding or die but no errors are being printed

PHP not posting onto mySQL database

This code should check for existing usernames and if there isn't one, it should create a new one. No matter what it won't add. Additionally, as you can see in the code it only echoes 'here' and doesn't echo 'not here'.
<?php
$password = "hey";
$username = "hi";
require "conn.php";
//$password = $_POST["password"];
//$username = $_POST["username"];
echo 'here';
$result = $conn->query("SELECT * FROM UserData WHERE username ='$username' ", MYSQLI_USE_RESULT);
echo 'not here';
if ($result) {
if($result->num_rows === 0)
{
$stmt = $conn->prepare("INSERT INTO UserData (username,password) VALUES (:username,:password)");
$params = array(
':username' => $username,
':password' => $password
);
$stmt->execute($params);
}
}
?>
This is the connection code:
<?php
//$db_name = "xxx";
//$mysql_username = "xxx";
//$mysql_password = "xxx";
//$server_name = "xxx";
// Create connection
$conn = new mysqli("xxx","xxx","xxx","xxx");
if ($conn->connect_error) {
die("Connection failed: " . $conn->connect_error);
}
echo "Connected successfully";
?>
Changes:
<?php
require "conn.php";
echo "debug 1";
$stmt = $conn->prepare("SELECT * FROM UserData WHERE username = ?");
$stmt->bind_param('s', /*$_POST["username"]*/ $username );
$username = 'hi';
$stmt->execute();
$stmt->store_result();
echo "debug 2";
if ($stmt->num_rows == 0){ // username not taken
echo "debug 3";
$stmt2 = $conn->prepare("INSERT INTO UserData (username, password) VALUES (?, ?)");
$password =(/*$_POST["password"]*/ "hey");
$username =(/* $_POST["username"]*/ "hi");
$stmt2->bind_param('s',$username);
$stmt2->bind_param('s',$password);
$stmt2->execute();
if ($stmt2->affected_rows == 1){
echo 'Insert was successful.';
}else{ echo 'Insert failed.';
var_dump($stmt2);
}
}else{ echo 'That username exists already.';}
?>
This code gets through all of the debugs but for some reason, it is still not inserting.
Replace this line
$result = **$mysqli->**query("SELECT * FROM UserData WHERE username ='$username' ", MYSQLI_USE_RESULT);
with following
$result = **$conn->**query("SELECT * FROM UserData WHERE username ='$username' ", MYSQLI_USE_RESULT);
The mysqli and PDO interfaces must not be mixed. Here the database connection and the SELECT query are both using the mysqli interface. But the second INSERT query is attempting to use the PDO interface, as evidenced by the use of named placeholders, and also the passing of a data array directly to execute(). The latter two features are not supported by mysqli, hence the code fails at the second query. Also, note that the second query is using prepared statements, while the first one is not. Again, different approaches should not be mixed together.
Also it appears that passwords are being stored as plain text, with no security. The proper approach is to use the password_hash function.
Just ensure that the database field has enough width (say 80-120 characters or more) to handle the current bcrypt hash, plus allow some more for future changes.
Staying with the mysqli interface (and with password_hash), the code could go something like this:
$stmt = $conn->prepare("SELECT * FROM UserData WHERE username = ?");
$stmt->bind_param('s', $_POST["username"]);
$stmt->execute();
$stmt->store_result();
if ($stmt->num_rows == 0){ // username not taken
$stmt2 = $conn->prepare("INSERT INTO UserData (username, password) VALUES (?, ?)");
$password = password_hash($_POST["password"], PASSWORD_DEFAULT);
$stmt2->bind_param('s', $_POST["username"]);
$stmt2->bind_param('s', $password);
$stmt2->execute();
if ($stmt2->affected_rows == 1)
echo 'Insert was successful.';
else echo 'Insert failed.';
}
else echo 'That username exists already.';
Note that the above approach would not be suitable for a high-traffic site, where there is a chance condition of another user trying to INSERT the same username, during the brief interval of time between the SELECT and INSERT database queries. That would require a different approach, like ensuring the subject database field is set to UNIQUE (which is good practice anyway), and then testing for violation of that UNIQUE field upon attempted duplicate insertion.
Assuming database and INSERT permissions are all set up OK and it is still not inserting, try enhancing the error-reporting.
Ensure the following are at the top of the page:
ini_set('display_errors', true);
error_reporting(E_ALL);
And put the following before the first query:
$driver = new mysqli_driver();
$driver->report_mode = MYSQLI_REPORT_ALL;
Then try again.

PHP file not retrieving data from my mySQL database server

I am currently coding an Android app for login and registration. I have discovered that the error is coming from my php file as when I try and just open the file it does not fetch any of the data even though it is connecting correctly to the database.
This is my PHP code here:
<?php
$con=mysqli_connect("mysql7.000webhost.com","a3736257_root","********","a3736257_UD");
if ($con->connect_error) {
die("Connection failed: " . $conn->connect_error);
}
//echo 'connection successful';
$username = 'jack';
$password = 'jackjack';
$statement = mysqli_prepare($con, "SELECT * FROM Parent WHERE username = ? AND password = ?");
mysqli_stmt_bind_param($statement, "ss", $username, $password);
mysqli_stmt_execute;
mysqli_stmt_store_result($statement);
mysqli_stmt_bind_result($statement,$parentID ,$username, $password, $email, $created, $rewardOwed);
$parent = array();
while(mysqli_stmt_fetch($statement)) {
$parent[username] = $username;
$parent[password] = $password;
$parent[email] = $email;
$parent[created] = $created;
}
echo json_encode($parent);
mysqli_stmt_close($statement);
mysqli_close($con); ?>
This is the output when I execute the code
The mysqli_stmt_execute function doesn't know what you want it to execute unless you provide it with the prepared statement. Also functions should have parenthesis ().
So:
mysqli_stmt_execute;
should be
mysqli_stmt_execute($statement);

PHP/MySQL: Check if username exists

I'm a beginner in php and I want to check if the username entered already exists.
Here is my code.
<?php
ini_set('display_errors',1);
error_reporting(E_ALL);
if (isset($_POST['submit'])) {
include "connect.php";
ValidateUser();
}
function ValidateUser()
{
if (!empty($_POST['username']) AND !empty($_POST['password'])) {
$queryrow=mysqli_query("SELECT * FROM websiteusers WHERE username = '$_POST['username']'");
if ($rows=mysqli_num_rows($queryrow)=0) {
RegisterUser();
}
}
function RegisterUser() {
echo "works up to here";
}
?>
It doesn't even give me an error despite turning error reporting on.
Have you even initialized a mysqli_connect?
$Connection = mysqli_connect("host","user","pass","database");
Then pass it to a function which uses mysqli_query() by:
function foo ($DB){
mysqli_query($DB,"QUERY HERE");
// Do other stuff
return /* Whatever you wish to return here*/
}
foo($Connection);
What you are trying to achieve can be done very easily with the following code. A bigger concern is security. It is good practice to both sanitize your input every time the user has a chance to input text.
Also, using prepared query's will put yet another layer of security.
Although this isn't using your provided code directly, I believe it is good to teach good habits.
If you have any questions feel free to ask.
$username = $_POST['username']; <-- sanitize this
$message = null;
$mysqli = new mysqli("localhost", "user", "password", "database");
$stmt = $mysqli->prepare("SELECT username FROM websiteusers WHERE username=?");
$stmt->bind_param('s', $username);
$stmt->execute();
$stmt->store_result();
$stmt->bind_result($usernamesql);
$stmt->fetch();
if ($stmt->num_rows() > 0) {
RegisterUser();
} else {
$message .= 'username already exists';
}
Later on when you require more items to be queried, or more results to be bound:
$stmt = $mysqli->prepare("SELECT username,password,other1,other2 FROM websiteusers WHERE username=?");
$stmt->bind_param('s', $username); <-- the "s" means the argument is a strings, if a argument is stored as an int use "i", but one character for each argument is required.
$stmt->execute();
$stmt->store_result();
$stmt->bind_result($usernamesql);
$stmt->fetch();
Multiple Arguments:
$stmt = $mysqli->prepare("SELECT username,password,other1,other2 FROM websiteusers WHERE username=? AND authenticated=?");
$stmt->bind_param('si', $username,$isauthenticated); <-- second argument is a INT or BOOL
$stmt->execute();
$stmt->store_result();
$stmt->bind_result($usernamesql,$passwordsql,$other1sql,$other2sql);
$stmt->fetch();
When your expecting multiple results, and lets say you want to dump them into arrays:
$userarray = array();
$stmt = $mysqli->prepare("SELECT username FROM websiteusers WHERE username=?");
$stmt->bind_param('s', $username);
$stmt->execute();
$stmt->store_result();
$stmt->bind_result($usernamesql);
while($stmt->fetch()){
array_push($userarray, $usernamesql);
}
$userarray is now an array of all the results fetched from the database.
Here is the right way to do this:
<?php
ini_set('display_errors',1);
error_reporting(E_ALL);
if (isset($_POST['submit'])) {
$mysqli = new mysqli("localhost", "user", "password", "database");
if ($mysqli->connect_errno) {
echo "Failed to connect to MySQL: (" . $mysqli->connect_errno . ") " . $mysqli->connect_error;
}
if(check_user($mysqli, $_POST['username']){
registerUser();
}else{
echo 'user exist, cannot register';
}
}
function check_user($conn, $username){
$query = "SELECT * FROM websiteusers WHERE username = ?";
if ($stmt = $conn->prepare($query)) {
$stmt->bind_param("s", $username);
$stmt->execute();
$stmt->close();
}
return $stmt->num_rows === 0;
}
function registerUser() {
echo "registering user ...";
}
Read up on prepared statement

fetching user id from login SQL table

I have recently switched my code from mysql to mysqli OOP for better practice. I am trying to fetch the user_id from my mysql table and save it in $_SESSION['user_id']. I have tried many different iterations of my code and worked on it for hours but no luck. As of now $_SESSION['user_id'] returns nothing. It works with my old mysql code so I know its not an issue with my table. I am still new at mysqli and I would greatly appreciate any help in this matter.
Here is the PHP:
<?php
session_start();
$con = new mysqli("localhost","root","pw","db");
if (mysqli_connect_errno()) {
printf("Connect failed: %s\n", mysqli_connect_error());
exit();
}
if(isset($_POST['submit'])){
$query = "SELECT * FROM tapp_login WHERE username = ? AND password = ? LIMIT 1";
$username = $_POST['user_name'];
$password = $_POST['pwd'];
$stmt = $con->prepare($query);
$stmt->bind_param('ss', $username, $password);
$stmt->execute();
$stmt->bind_result($username, $password);
$stmt->store_result();
if($stmt->num_rows == 1){ //To check if the row exists
while($row = $stmt->fetch()){ //fetching the contents of the row
$_SESSION['user_id'] = $row[1];
$_SESSION['LOGIN_STATUS']=true;
$_SESSION['user_name'] = $username;
echo 'true';
}
}
else {
echo 'false';
}
$stmt->free_result();
$stmt->close();
}
else{
}
$con->close();
?>
The validation works and the user name is successfully stored in the session. I think the error is in the $row = $stmt->fetch() but I cannot figure it out. Thanks in advance!
I think the issue is this line:
$_SESSION['user_id'] = $row[1];
I believe it should either be $row[0] or $row['user_id'].
(note: I used 'user_id', but it would be the name of the column that holds the IDs)

Categories