How to fix "Array index out of range?" - php

When logging into my Unity project, I get error "Array index is out of range" at this line of my C# code
if (www.text[0] == '0')
www.text pulls from this php script (www.text is returning null when debugging so it must be an error with my script).
<?php
$con = mysqli_connect('localhost', 'root', 'root', 'unityaccess');
//check that connection happened
if (mysqli_connect_errno())
{
echo "1: Connection failed"; //error code #1 = connection failed
exit();
}
$username = $_POST["name"];
$password = $_POST["password"];
//check if name exists
$namecheckquery = "SELECT username, salt, hash, score FROM players WHERE
username = ' " . $username . "';";
$namecheck = mysqli_query($con, $namecheckquery) or die("2: Name check query
failed"); //error code #2 - name check query failed
if (mysqli_num_rows($namecheck) != 1)
{
echo "5: Either no user with name, or more than one";
exit();
}
//get login info from query
$existinginfo = mysqli_fetch_assoc($namecheck)
$salt= $existinginfo["salt"];
$hash = $existinginfo["hash"];
$loginhash = crypt($password, $salt);
if($hash != $loginhash)
{
echo "6: Incorrect password"; //error code #6 - password does not hash to
match table
exit();
}
echo "0\t" . $existinginfo["score"];
?>
I'm following a tutorial and am new to php and sql.
https://www.youtube.com/watch?v=NVdjlXgbiMM
In the tutorial his code is exactly the same as mine. Looking at it myself I would assume that the echo "0\t" . $existinginfo["score"]; is the problem, and that putting a tab isn't separating it into an array. In his code he runs it and it's fine though, so I must be missing something else?

You have a space after the ' in the query on this line:
$namecheckquery = "SELECT username, salt, hash, score FROM players WHERE
username = ' " . $username . "';";
So if the username entered is user1 it will look in the database for <space>user1 (where <space> means a space character). Remove that space.
$namecheckquery = "SELECT username, salt, hash, score FROM players WHERE
username = '" . $username . "';";
Actually, it would be even better if you learned to use prepared statements, then problems like this are nearly impossible, as well as making the code safe from SQL-injection. Read How can I prevent SQL injection in PHP?

Related

MySqli adding multiple rows to db

I'm sending data to a db from a web form but every time I run it the data is stored in the db in six new rows rather than just one.
The form is just a standard form with inputs for email/password and a submit button. The action of the form runs this:
<?php
// connect to db
$link = new mysqli("localhost", "root", "", "db_name");
if (!$link) {die('Database Error: Could not connect: ' . mysql_error());}
// username and password sent from form
$email = $_POST['email'];
$password = ($_POST['password']);
// encrypt
$salt = substr(base64_encode(mcrypt_create_iv(16, MCRYPT_DEV_URANDOM)), 0, 16);
$em = crypt($email, '$6$'.$salt);
$pw = crypt($password, '$6$'.$salt);
// insert to db
$insert = "INSERT INTO users (email, password) VALUES ('$em', '$pw')";
$link -> query($insert);
// check succes/fail
if ($link->query($insert) === TRUE) {
echo "New record created successfully";}
else {
echo "Error: " . $sql . "<br>" . $link->error;
}
// close the db connection
$link->close();
I know this brings up a question about sanitizing inputs with encryption/salting. This page says that it's a reasonable method. Please feel free to bring that up, but I'm not really looking for an argument over best practices for sanitizing user inputs.
I'm wondering if anyone cal tell me why the data would be stored 6 times instead of just once. I changed the $6$ to $1$ but it still added 6 rows.
You have some silly seo-friendly links implementation on your site that makes it run your php code on every reques, and 5 links to non-existent resources in your html.

use mysql result in php string

I am trying to do a simple login script with php, my issue is the part that takes the password of the user out of the database to compare it with what has been entered.
Right now my code does not compare, but echo the password so i can see its working before going further, yet... i cannot get the password, my SQL query works fine, tried it in phpmyadmin. but the echo does not show anything! i dont get it.
$account = $_POST['account'];
$password = $_POST['password'];
$con=mysqli_connect($mysql_host,$mysql_user,$mysql_password,$mysql_database);
if (mysqli_connect_errno()) {
echo "Failed to connect to MySQL: " . mysqli_connect_error();
}
else {
$query = "SELECT password FROM account WHERE login = '$account'";
$result = mysqli_query($con, $query);
$pass = $row['password'];
echo "$pass";
}
You forgot to actually FETCH your query's results:
$result = mysqli_query($con, $query);
$row = mysqli_fetch_assoc($result); // you forgot this
And beyond that, you're vulnerable to sql injection attacks.

Php log in allows entry with no user/pass

Hey guys ive put together a basic user log in for a secure admin area and it seems to work great, if you enter a correct user/pass you get access, if you enter the wrong user pass, you get no access. However if you enter nothing in both fields you get access.
This is how it works.
Creating a user, a basic form POSTS to this php file.
<?php
$con = mysqli_connect(credentials are all good) or die(mysqli_error($con)) ;
$escapedUser = mysqli_real_escape_string($con, $_POST['user']);
$escapedPass = mysqli_real_escape_string($con, $_POST['pass']);
$some_str = md5(uniqid(mt_rand(), true));
$base_64str = base64_encode($some_str);
$modified_base64 = str_replace('+', '.', $base_64str);
$gensalt = substr($modified_base64, 0, 22);
$format_str = "$2y$10$"; // 2y for Blowfish and 10 times.
$salt = $format_str . $gensalt . "$";
$hashed_pass = crypt($escapedPass, $salt);
$query = "INSERT INTO `userpass` (`username`, `password`, `salt`) VALUES ('$escapedUser', '$hashed_pass', '$salt'); ";
if(isset($escapedUser) && isset($hashed_pass))
{
mysqli_query($con, $query);
header("Location: ausers.php");
exit();
}
Echo "Something went wrong!";
?>
The database appears to be storing these fine
We then log in with this code
<?php
$con = mysqli_connect(again credentials are fine) or die(mysqli_error($con)) ;
$escapedUser = mysqli_real_escape_string($con, $_POST['user']);
$escapedPass = mysqli_real_escape_string($con, $_POST['pass']);
$saltQuery = "select salt from userpass where username = '$escapedUser';";
$result = mysqli_query($con, $saltQuery);
$row = mysqli_fetch_assoc($result);
$salt = $row['salt'];
$hashed_pass = crypt($escapedPass, $salt);
if(isset($escapedUser) && isset($hashed_pass))
{
$userQuery = "SELECT * FROM userpass WHERE username='$escapedUser' AND password='$hashed_pass'";
$userpass = mysqli_query($con, $userQuery);
$count = mysqli_num_rows($userpass);
if($count == 1)
{
$_SESSION['username'] = $escapedUser;
header("location: aindex.php");
exit();
}
header("Location: alogin.htm");
exit();
}
Echo "Something went wrong!";
?>
So as i said, this seems to work fine for when any user pass combination is given whether access granted or denied however using no user and pass and pressing log in allows entry. Any ideas? THeres no blank rows in the database table.
Side question, is this salt/hash method correct, its my first attempt.
For your login code, your condition relies on an isset() test. You perform this test on $escapedUser and $hashed_pass. Both of these variables were actually assigned values earlier in the code! Once you assign a value to the variable, it will pass the isset() test, even if the value is an empty string. You might want to use an empty() check, perhaps on the original $_POST variables.
Moving on to the inner condition, which tests if the mysql query returns exactly 1 row of results. If there were truly no rows with empty values, then this condition would never pass because the query would return 0 rows. But it is passing. Two things to consider:
Notice that your registering code uses the same isset() test. Therefore it is very possible that someone used your registration form, submitted empty fields, and successfully registered a row with empty user and password fields. Have you explicitly queried your database for empty fields and actually come up with 0 results?
Your query uses SELECT *. Perhaps this is causing the query to return some sort of aggregate value (like a COUNT() or something that always has a result no matter what). Perhaps try explicitly defining the columns to return?
I cannot comment on your salt/hash method as I have no experience in that part. Hope you find this helpful!
In my opinion you need more than one level of checks in any form, whether it be registration, comments, login, etc. The way I prefer to go about it is a tiered approach. It may work better for you, but it's just an example.
By doing it this way, you ensure that your input will never be empty. Another issue I see with your login script is that you never compare the input with the database so how can you know if they entered the correct information? The only thing allowing them to login is that the query returned a record. This is also why they can login with a blank form.
<?php
$con = mysqli_connect(again credentials are fine) or die(mysqli_error($con)) ;
/* Ensures that form was submitted before any processing is done */
if (isset($_POST)) {
$User = $_POST['user']);
$Pass = $_POST['pass']);
if (!empty($User)) {
if (!empty($Pass)) {
$escapedUser = mysqli_real_escape_string($con, $User);
$escapedPass = mysqli_real_escape_string($con, $Pass);
/* you need to verify the password here, before adding the salt */
$saltQuery = "select salt from userpass where username = '$escapedUser'";
$result = mysqli_query($con, $saltQuery);
$row = mysqli_fetch_assoc($result);
$salt = $row['salt'];
$hashed_pass = crypt($escapedPass, $salt);
$userQuery = "SELECT * FROM userpass WHERE username='$escapedUser' AND password='$hashed_pass'";
/* you need to verify the username somewhere here */
$userpass = mysqli_query($con, $userQuery);
$count = mysqli_num_rows($userpass);
if($count == 1)
{
$_SESSION['username'] = $escapedUser;
header("location: aindex.php");
exit();
} else {
header("Location: alogin.htm");
exit();
}
} else {
echo "Please enter a password.";
}
} else {
echo "Please enter a username.";
}
} else {
echo "You have not entered any information.";
}
?>

universal login name

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

PHP MD5 Create User Form

I have used a tutorial here: http://www.phpeasystep.com/phptu/26.html to create a login form for my website. I have set the uPassword field in my database to be md5 and all of the passwords in the database are encrypted with md5.
The login works perfectly, however I am slightly confused about creating a registration form.
The form requests for a user to input their desired password. I am slightly confused as to how I will then take the password that the user inputs, converting it to md5 and then inputting the md5 password into the uPassword field in the user table.
Below is the code that I have for the processresgistration.php file:
/* Database connection info*/
mysql_select_db("dbname", $con);
$encryptedpassword = md5($_POST['uPassword']);
md5($uPassword);
$sql="INSERT INTO users (uName, uPassword, uSurname, uFirstName)
VALUES
('$_POST[uName]','$encryptedpassword','$_POST[uSurname]','$_POST[uFirstName]'";
if (!mysql_query($sql,$con))
{
die('Error: ' . mysql_error());
}
echo "Account created. You can now login";
mysql_close($con)
?>
The code above is supposed to:
Create a variable named encryptedpassword
Use uPassword as encryptedpassword
Convert encrypted password to MD5
Input the MD5 password into the users table as uPassword
I'm sure that I've not used a correct variable somewhere, or I have done a simple error with my syntax; any comments/help is greatly appreciated!
Thanks,
Chris M
You code require some validation & escaping, more like this :
<?php
/* Database connection info */
mysql_select_db("dbname", $con);
if ($_REQUEST['METHOD'] == 'POST') {
$uName = filter_input(INPUT_POST, 'uName');
$uPassword = filter_input(INPUT_POST, 'uPassword');
$uSurname = filter_input(INPUT_POST, 'uSurname');
$uFirstName = filter_input(INPUT_POST, 'uFirstName');
// do some validation here ...
// if everything OK, then crypte the password
$hashedPassword = md5($uPassword);
// and store it
$sql = sprintf(
'INSERT INTO users (uName, hashedPassword, uSurname, uFirstName)
VALUES (%s, %s, %s, %s);',
mysql_real_escape_string($uName, $con),
mysql_real_escape_string($hashedPassword, $con),
mysql_real_escape_string($uSurname, $con),
mysql_real_escape_string($uFirstName, $con)
);
if (!mysql_query($sql,$con)) {
die('Error: ' . mysql_error());
}
mysql_close($con);
echo "Account created. You can now login";
}
?>
Now for login
<?php
if ($_REQUEST['METHOD'] == 'POST') {
$uName = filter_input(INPUT_POST, 'uName');
$uPassword = filter_input(INPUT_POST, 'uPassword');
$hashedPassword = md5($uPassword);
$sql = sprintf(
'SELECT * FROM users WHERE uName = "%s" AND hashedPassword = "%s" LIMIT 1',
mysql_real_escape_string($uName, $con),
mysql_real_escape_string($hashedPassword, $con),
);
// etc etc ...
}
?>
/* Database connection info*
You didn't properly close your comment there. Add a / at the end of the line.
Oh, and MD5 is insecure. Use SHA1 instead. Or even better, use salted SHA1.
You also need to start escaping all user input you are putting in your database using mysql_real_escape_string() or Little Bobby Tables will have lots of fun with your database.
/* Database connection info*/
mysql_select_db("dbname", $con);
$encryptedpassword = md5($_POST['uPassword']);
$sql="INSERT INTO users (uName, uPassword, uSurname, uFirstName)
VALUES
('$_POST[uName]','$encryptedpassword','$_POST[uSurname]','$_POST[uFirstName]')";
if (!mysql_query($sql,$con))
{
die('Error: ' . mysql_error());
}
echo "Account created. You can now login";
mysql_close($con)
?>
The closing of bracket is the issue in query
('$_POST[uName]','$encryptedpassword','$_POST[uSurname]','$_POST[uFirstName]'";
This needs a closing ' ) '

Categories