Check if username or email is taken? - php

I understand that this may be a duplicate post, although I am unsure how to use the posts answers in my context. I am trying to post the registered fields to the database, but if they are taken (only username and email), return to the form where the user can then edit the wrong information. Could anyone help?
I am aware that I am using deprecated tags, this is for a college project
if (isset($_POST['firstname'], $_POST['surname'], $_POST['email'], $_POST['username'], $_POST['password'], $_POST['interest'])){
$firstname = ($_POST['firstname']);
$surname = ($_POST['surname']);
$username = ($_POST['username']);
$password1 = ($_POST['password']);
$email = ($_POST['email']);
$interest = ($_POST['interest']);
$result = mysql_query("INSERT INTO user (firstname,surname,username,password,email,interestarea,user_type) VALUES ('$firstname','$surname','$username','$password1','$email','$interest','normal')");
}
if (isset($_POST['submit']))
{
?>
<script>window.location='redirect.html';</script>
<?php
}
?>
I did have something like this, but this does not work
$query2="SELECT * FROM user WHERE username='$username'";
$result2=mysql_query($query2);
$num=mysql_numrows($result2);
if ($num!=0)
{
echo "That username has already been taken, please try again<br>
<a href='register.php'>Register</a>";
exit();
}

The function is mysql_num_rows instead of mysql_numrows:
$num = mysql_num_rows($result2);
mysql_num_rows
As the page also tells you, from PHP 5.5.0, this method can not be used anymore. So suggest start using mysqli_* or PDO

Related

Comparing MD5 hashed passwords is not working

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.

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.";
}
?>

How to adapt my PHP Session into an Array

I have this PHP code which I'm using to trigger the user log in. For a successful log in, the user uses their registered email and password. My current PHP code allows the username to be echoed on whatever pages use the $_SESSION['loggedin'] = $dbusername. What I'm now trying to do is to adapt this PHP code to put an Array into the 'loggedin' session. I want the array to hold user registration details i.e firstname, lastname, company and email, aswell as their username (dbusername). This is to enable me to echo such details on a 'user account page'
My code:
<?php
session_start();
$email = $_POST['email'];
$password = $_POST['password'];
if ($email&&$password)
{
$connect = mysql_connect("*****","***","**********") or die ("Login failed!");
mysql_select_db("dbname") or die ("Could not connect to Database");
$query = mysql_query("SELECT * FROM regusers WHERE email='$email'");
$numrows = mysql_num_rows($query);
if($numrows !=0)
{
while ($row = mysql_fetch_assoc($query))
{
$dbemail = $row['email'];
$dbpassword = $row['password'];
$dbusername = $row['username'];
}
if ($email==$dbemail&&$password==$dbpassword)
{
include 'loginIntro.php';
$_SESSION['loggedin']=$dbusername;
}
else
echo "Incorrect Password";
}
else
die ("That email doesn't exist");
}
else
die ("Enter a registered email and password");
?>
Then on my 'user account page' I have this :
<?php
session_start();
$dbusername = $_SESSION['loggedin'];
?>
For the purposes of echoing the username this PHP code works fine, as all I have to do is : any time I want to display the users username. So going back to my original question - Please impart the necessary knowledge to adapt this PHP code to hold the users registration details so I can echo such details on whatever page(s) use the session in question. Please forgive my lack of knowledge and understanding, I've scratched my head so hard I've got cradle cap - which only babies get, but in this PHP game I'm an embryo. Thanks for whatever help comes
$_SESSION is a array
You can simply save a associative array inside of it.
$_SESSION['id'] = $x;
$_SESSION['username'] = $y;
$_SESSION['realname'] = $z;
or a nested array
$_SESSION['user']['id'] = $x;
$_SESSION['user']['username'] = $y;
$_SESSION['user']['realname'] = $z;
Beware
You are using deprecated functions.
There is no validation on data passed.
There is a risk (looks like 100%) of SQL injection.
As bwoebi said, you may not save password in clear text.
Suggested reading
http://php.net/manual/en/function.error-reporting.php
http://php.net/manual/en/language.types.array.php
http://www.php.net/manual/en/session.examples.basic.php
http://php.net/manual/en/filter.examples.validation.php
http://php.net/manual/en/faq.passwords.php
http://php.net/manual/en/security.database.sql-injection.php
http://php.net/manual/en/intro.pdo.php
If you want to use an Array as a Session variable, you have to serialize it first. (http://php.net/manual/en/function.serialize.php).
Then you can add it to $_SESSION, and unserialize (http://php.net/manual/en/function.unserialize.php) it on the other pages.
Now here are two advices : hash your passwords using sha1 (http://us2.php.net/manual/en/function.sha1.php), and don't use mysql_* functions, which are outdated. Consider using mysqli ou PDO.

inserting variable into database with php

I'm editing part of a user login system and I'm very confused on one issue. I'm trying to allow the user to change their username using their email as a reference for the lookup. For some reason I can't get the $email variable to set properly. When I change the variable $email to an address that I know is in my database (meaning I remove $email and change it to an address that exists) the username is properly changed. When I swap it back to $email, nothing happens.
The strange part is when I echo $email, the correct email address is displayed. I can't figure out why it won't let me do this despite it being echoed properly. Is it possible to not be a string despite an email address being displayed?
I understand about sql injections. I'm just trying to keep the code as simple as possible for now so I can get the functionality working first.
<?
if (isset($_POST['submit'])) {
$email = $user->get_email($username);
$newuser = $_POST['newusername'];
$server = 'localhost';
$usern = 'root';
$pass = '';
$connection = mysql_connect($server, $usern, $pass) or die(mysql_error());
mysql_select_db(testdb, $connection) or die(mysql_error());
if(isset($username)) {
mysql_query("UPDATE users SET username='$newuser' WHERE email = '$email'") or die(mysql_error());
}
}
?>
Also, when I change the query statement so that the reference value is the userid, the username is correctly inserted. From this I know that $email isn't being set properly.
mysql_query("UPDATE users SET username='$newuser' WHERE userid = '$userid'") or die(mysql_error());
if(isset($username)) {
mysql_query("UPDATE users SET username='$newuser' WHERE email = '$email'") or die(mysql_error());
}
Where in your code are you setting the $username variable? If it's not set, your update won't run. You should probably go back and review your variable names and make sure they're consistent (and set) throughout the rest of the page.
Sounds like your get_email() function is returning a bad address.
Are you sure your authentication system is working fine in all other ways?
What happens when you do this:
echo "UPDATE users SET username='$newuser' WHERE email = '$email'";
Also, you will want to sanitize your input for $newuser to avoid SQL injection. Like one of the comments said, you should be using the user id instead of email. I am not sure what authentication class you are using, but you should be able to find something like $user->returnID() and update using that.
Anyway it's recommend to add
$email = mysql_real_escape_string($email);
Maybe that's the problem
I should use the following:
<?
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
$email = $user->get_email($username); // where does $username come from anyway? and where are you initiating the $user object?
$newuser = $_POST['newusername'];
$server = 'localhost';
$usern = 'root';
$pass = '';
$connection = mysql_connect($server, $usern, $pass) or die(mysql_error());
mysql_select_db(testdb, $connection) or die(mysql_error());
if(isset($newuser)) {
$newuser = mysql_real_escape_string($newuser);
$email = mysql_real_escape_string($email);
mysql_query("UPDATE users SET username='" . $newuser . "' WHERE email = '". $email ."'") or die(mysql_error());
}
}
?>
The mysql_real_escape_string() creates a new string. It will escape characters which probably can damage your database when they are putted in. (Called: SQL Injection)
For examples of SQL Injection to give you an idea what it is, and how it can be used and protected:
http://www.unixwiz.net/techtips/sql-injection.html

How to improve login script?

How can I ensure my login script is secure and make it better, This is my first code:
Help is most appreciated.
<?php
include ('../includes/db_connect.php');
$firstname = $_POST['firstname'];
$lastname = $_POST['lastname'];
$email = $_POST['email'];
$mobile = $_POST['mobile'];
$username = $_POST['username'];
$password = md5($_POST['password']);
// lets check to see if the username already exists
$checkuser = mysql_query("SELECT username FROM users WHERE username='$username'");
$username_exist = mysql_num_rows($checkuser);
if($username_exist > 0){
echo "I'm sorry but the username you specified has already been taken. Please pick another one.";
unset($username);
header("Location: /registration?registration=false");
exit();
}
// lf no errors present with the username
// use a query to insert the data into the database.
$query = "INSERT INTO users (firstname, lastname, email, mobile, username, password)
VALUES('$firstname', '$lastname','$email', '$mobile','$username', '$password')";
mysql_query($query) or die(mysql_error());
mysql_close();
echo "You have successfully Registered";
header("Location: /registration?registration=true");
// mail user their information
//$yoursite = ‘www.blahblah.com’;
//$webmaster = ‘yourname’;
//$youremail = ‘youremail’;
//
//$subject = "You have successfully registered at $yoursite...";
//$message = "Dear $firstname, you are now registered at our web site.
// To login, simply go to our web page and enter in the following details in the login form:
// Username: $username
// Password: $password
//
// Please print this information out and store it for future reference.
//
// Thanks,
// $webmaster";
//
//mail($email, $subject, $message, "From: $yoursite <$youremail>\nX-Mailer:PHP/" . phpversion());
//
//echo "Your information has been mailed to your email address.";
?>
Follow Artefacto's advice about SQL injection and Hashing passwords in the database. Other things ...
echo "I'm sorry but the username you specified has already been taken. Please pick another one.";
unset($username);
header("Location: /registration?registration=false");
Wont work because you can't echo then send a header. Headers must be sent before any output.
Also, there is no point doing this:
header("Location: /registration?registration=false");
echo "I'm sorry but the username you specified has already been taken. Please pick another one.";
unset($username);
The webbrowser will redirect straight away and the user won't see the handy message you've printed.
Also, it's usual to ask for 2 password fields on registration forms incase the user made a typo and didn't notice because all the text was *'s. You compare the 2 and if they are different you assume a typo was made and ask again.
That's not a login script. It's a registration script.
See SQL injection in the PHP manual. Your program is vulnerable to this kind of attacks.
Also, don't just or die(mysql_error()). This will expose information about your database that you may not want to expose (table names, etc.). Use proper error handling. For instance, you can throw an exception and define a uncaught exception handler that shows a "oops" page and logs the error.
Finally, use hashes strong than MD5, such as sha1.
As said by #Artefacto, that's not a login script.
But if you intend to do a login script I would like to give you a suggestion. I've done this a while ago.
Instead of doing something like this:
$sql = "SELECT * FROM users WHERE username = '$username' AND password = '$password'";
I would do this:
$sql = "SELECT * FROM users WHERE username = '$username'";
$user = //use the php-sql (query, fetch_row) commands to fetch the user row.
if (strcmp($user['password'], $password) == 0) {
//log in success
}
By doing this, you avoid SQL Injection in a simple and elegant way. What you guys think about it?
To reiterate what everyone else mentioned. It's important to protect yourself (and sever) from SQL injection. For example:
$checkuser = mysql_query("SELECT username FROM users WHERE username='$username'");
You're just simple taking the value from $_POST['username'] and placing it in the variable $username.
Some people aren't very nice and will try to break your program :( So it's always recommended to escape any data that was taken from a user, before placing it into an SQL query.
For instance...
This:
$checkuser = mysql_query("SELECT username FROM users WHERE username='$username'");
Becomes:
$checkuser = mysql_query("SELECT username FROM users WHERE username='" .mysql_real_escape_string($username). "'");

Categories