want to stop users entering invalid email addresses into form - php

I would like to be able to run a php validate script to stop users form entering gibberish as their email address. I know we can have the form input type as email but that can be easily bypassed in developer tools and the database integrity damaged.
My insert page looks like this:
$email = $conn->real_escape_string($_POST['emailpost']);
$password = $conn->real_escape_string($_POST['passpost']);
$firstname = $conn->real_escape_string($_POST['firstnamepost']);
$lastname = $conn->real_escape_string($_POST['lastnamepost']);
$phonenumber = $conn->real_escape_string($_POST['phonenumberpost']);
$education = $conn->real_escape_string($_POST['institutionpost']);
$facebook = $conn->real_escape_string($_POST['facebookpost']);
$twitter = $conn->real_escape_string($_POST['twitterpost']);
$instagram = $conn->real_escape_string($_POST['instagrampost']);
$filename = $_FILES['uploadprofileimg']['name'];
$filename = $ran.$filename;
$filetmp = $_FILES['uploadprofileimg']['tmp_name'];
$filetype = $_FILES['uploadprofileimg']['type'];
move_uploaded_file($filetmp, "../userimages/".$filename);
$insertuser = "INSERT INTO elmtree_users (user, email, pw, firstName, lastName, profileimg, learninginstitute, phone, facebook, twitter, instagram) VALUES
('$username', '$email', '$password', '$firstname', '$lastname', '$filename', '$education', '$phonenumber', '$facebook', '$twitter', '$instagram')";
$resultinsert = $conn -> query($insertuser);
if(!$resultinsert){
echo $conn->error;
}else{
echo "<h2> Account successfully registered!</h2>
<h4>Please <a href='login.php'> <font class='text-success'><strong>login.</strong></font></a></h4><br><br><br><br>";

Like everyone is pointing out
making your own logging system is tricky. it required you to do additional steps to make the content secured. Not only to hackers but you as administrator of the database shouldn't have access to see your customers password in PlainText Most users will use the same password on your site as they used for there email password they registered with on your site..
It is more advisable to create login tools like laravel, Or simply research how to build a secure login system, because what we are seeing here in your code, is BAD, Not syntactically, but from a security stand point.
Me knowing you store passwords like that, I wouldn't register onto your website.
Any how not only that, But you really should have a look into mysqli binding
Or even, and something I like better is PDO_Mysql
Your code will not only be more clear to read, but will bind values directly to a a field within mysql ( no need to use real_escape_string no more )
Now to actually answer your question.
You probably should make some kind of javascript live validator on the field of your form directly.
then on PHP side, You can do a simple condition with REGXP and preg_match()
Have a look at https://regex101.com/r/SOgUIV/1 this is a regex that will validate EMAILs.
With this link, You should then experiment a bit with it, it has not only documentation on the side but also possibles quantifier and such.
if(preg_match("/^((?!\.)[\w-_.]*[^.])(#\w+)(\.\w+(\.\w+)?[^.\W])$/i",trim($_POST['Email']))){
//What ever is in here will get process when $_POST['emailpost'] is valid.
}
Edited ----
As some user pointed out in comments.
You would probably be better of using
if(filter_var($_POST['emailpost'],FILTER_VALIDATE_EMAIL){
//What ever is in here will get process when $_POST['emailpost'] is valid
}
Also if you want to make sure user has access to the email address account, You could also add two column within your users table, isConfirmed,ConfirmationCode
When the user register, You create a unique code and put it into ConfirmationCode then send the user an email with something along those line "Please click the following link to activate account www.yourWebSite.com/confirmationPage.php?Code=$TheActualCodeYouCreatedForThatUser"
Then once user get to that page, Change the field isConfirmed to '1' or true.
Once there on your website, you will be able to assume that only emails with isConfirmed is a real user.

To validate email you need to check a lot of stuff like
if the email already exists
if its a real email i.e check for presence of #
check for funny characters which are not supposed to be in an email.
then always encrypt your password
if ($_POST['submit']) {
$errors = array();
$email = $conn->real_escape_string($_POST['emailpost']);
$password = $conn->real_escape_string($_POST['passpost']);
$firstname = $conn->real_escape_string($_POST['firstnamepost']);
$lastname = $conn->real_escape_string($_POST['lastnamepost']);
$phonenumber = $conn->real_escape_string($_POST['phonenumberpost']);
$education = $conn->real_escape_string($_POST['institutionpost']);
$facebook = $conn->real_escape_string($_POST['facebookpost']);
$twitter = $conn->real_escape_string($_POST['twitterpost']);
$instagram = $conn->real_escape_string($_POST['instagrampost']);
$filename = $_FILES['uploadprofileimg']['name'];
$filename = $ran.$filename;
$filetmp = $_FILES['uploadprofileimg']['tmp_name'];
$filetype = $_FILES['uploadprofileimg']['type'];
move_uploaded_file($filetmp, "../userimages/".$filename);
if (strlen($email) && strlen($password) && strlen($firstname) && strlen($lastname) && strlen($phonenumber) && strlen($education) && strlen($facebook) && strlen($twitter) && strlen($instagram)) {
//check for a valid email
if(preg_match("^[_a-z0-9-]+(\.[_a-z0-9-]+)*#[a-z0-9-]+(\.[a-z0-9-]+)*(\.[a-z]{2,3})$^",$email))
$errors['email'] = 'invalid email address';
//check for presence of # in email
if (!stristr($em,"#") OR !stristr($em,".") $errors['email'] = 'please enter an email';
//echeck if email already exists in database
$checkemail = $conn->get_row("SELECT * FROM elmtree_users WHERE email=".$email);
if( $conn->num_rows( $checkemail ) > 0 ) $errors['email'] = "User already exists with the email: " . $email;
//validate password
$minpasslen = 8;
if (strlen($password) < $minpasslen)
$errors['email'] = 'password is too short';
$finalpassword = MD5($password);
if (empty($errors)) {
$insertuser = "INSERT INTO elmtree_users (user, email, pw, firstName, lastName, profileimg, learninginstitute, phone, facebook, twitter, instagram) VALUES
('$username', '$email', '$finalpassword', '$firstname', '$lastname', '$filename', '$education', '$phonenumber', '$facebook', '$twitter', '$instagram')";
$resultinsert = $conn -> query($insertuser);
if(!$resultinsert){
echo $conn->error;
} else {
echo "<h2> Account successfully registered!</h2>
<h4>Please <a href='login.php'> <font class='text-success'><strong>login.</strong></font></a></h4><br><br><br><br>";
} else {
echo implode('<br>', $errors);
}
}
}

Related

Form works without check but stops won't insert with check

I am trying to preform a quick check on the email entered by a user and provide user with an error if the email field is not unique. I have setup the database to keep this field unique now its about telling the user what they did wrong.
If I run the script below without the email check I can insert values into the table fine. All messages work and the table updates if it is a new email.
But when I add the email check code it will recognize a bad entry and provide the error but it will not proceed to enter the values if the email is good.
<?php
require('connect.php');
// If the values are posted, insert them into the database.
if (isset($_POST['rname']) && isset($_POST['email'])){
$rname = $_POST['rname'];
$fname = $_POST['fname'];
$email = $_POST['email'];
$emailcheck = "select email from entries where email = ".$email."";
if (mysql_num_rows != 1)
{
$err = "Error email already registered!";
} else {
$query = "INSERT INTO `entries` (rname, fname, email) VALUES ('$rname', '$fname', '$email')";
$result = mysql_query($query);
if($result){
$msg = "Thanks, you have successfully registered.";
}
}
}
?>
Trouble code is this section here
$emailcheck = "select email from entries where email = ".$email."";
if (mysql_num_rows != 1)
{
$err = "Error email already registered!";
} else {
You have to enclose the strings in a query within quotes and have to execute it using mysql_query(). Both are missing in your code.
$emailcheck = mysql_query("select email from entries where email = '$email'");
Also the syntax for mysql_num_rows() is wrong in your code. It should be :
int mysql_num_rows ( resource $result )
ie,.
if (mysql_num_rows($emailcheck ) >0 ) // if email already exists
{
$err = "Error email already registered!";
}
try this
and please remember this is only temparary form. and ugly one too. so dont worry about it use your original form.
<?php
require('connect.php');
// If the values are posted, insert them into the database.
if (isset($_POST['rname']) && isset($_POST['email'])){
$rname = $_POST['rname'];
$fname = $_POST['fname'];
$email = $_POST['email'];
$emailcheck = mysql_query("select email from entries where email = '$email'");
if (mysql_num_rows($emailcheck) >0)
{
$err = "Error email already registered!";
echo $err;
} else {
$query = "INSERT INTO `entries` (rname, fname, email) VALUES ('$rname', '$fname', '$email')";
$result = mysql_query($query);
if($result){
$msg = "Thanks, you have successfully registered.";
echo $msg;
}
}
}
?>
//the form is here just for reference. as you can see all the type are text. i just made it to check
//weather it going to work or not
<form action="" method="post" enctype="multipart/form-data">
<input type="text" name="rname"><br>
<input type="text" name="fname"><br>
<input type="text" name="email"><br>
<input type="submit" value="Upload file">
</form>
It generated the same "Warning: mysql_num_rows(): supplied argument is not a valid MySQL result resource" error. Thank you for your try.
While I still don't understand why my fix worked when the code I posted here did not but I found a solution. By moving the check for duplicate emails to an else statement after the insert I am able to run that check and produce an error message for users. Since the database is configured to reject duplicate entries this option will work. I can now focu my efforts on escaping all entries and trying to ensure the script is hardened against hacking attempts.
Thanks for your efforts.

How to build restriction on user availability during registration using PHP?

I have code that registers users by providing their username, email and password. Now I want to restrict the users to allow only if new username that are not saved into the database. If he/she inputs new username then message should alert notifying that the username you have entered is not available.
The code I have used is below in register.php
<?php
include"connection.php";
if (!isset($_POST['submit'])) //if the user clicks the submit button then the PHP code POST the details
{
$user_name = $_POST['username'];
$user_password = $_POST['password'];
$user_email = $_POST['email'];
if($user_name && $user_password && $user_email)
{
$query = mysql_query("INSERT INTO users (username, password, email, type)
VALUES ('$user_name', '$user_password', '$user_email', '0')");
mysql_query($query);
echo '<script type="text/javascript">alert("You have been registered");</script>';
}
else {
echo '<script type="text/javascript">alert("All fields required");</script>';
header("location:user_create.html");
}
}
?>
First of all:
filter data! Users can send unsafe data, so you should use mysql_escape_string() function (it's minimal requirement). Read about SQL Injection and XSS.
hash password! Minimal requirement is to use md5 function, read about password hashing: http://www.php.net/manual/en/faq.passwords.php
Use SQL query to check if user login is available:
$result = mysql_query('SELECT * FROM users WHERE username="'.mysql_escape_string($_POST['username']).'"');
if(mysql_fetch_array($result)) {
// username is unavailable, do something ....
}
else {
// register user
}
Notice, that mysql function are deprecated from PHP 5.5. Use PDO functions instead.
Use a UNIQUE key in the db for the username field. Then you can use mysql_error() to catch the error and to show user that he can't use that username because it is already stored in the db.

Values are not being added to the database

I am very new to PHP and Mysql. I have made a registeration form but the values being inputted are not being saved in my database. I don't know why. I am connected to the database. Could anyone give me some insight? By the way, I know you are going to say "Mysql" is deprecated. But I am just starting out and learning how all of this works. As soon as I have a thorough understanding of the processes I am going to change my code to Mysqli...
<?php
//form data
$submit = strip_tags($_POST['submit']);
$fname = strip_tags($_POST['fname']);
$lname = strip_tags($_POST['lname']);
$usernamereg = strip_tags($_POST['usernamereg']);
$passwordreg = strip_tags($_POST['passwordreg']);
$email = strip_tags($_POST['email']);
$emailcheck = strip_tags($_POST['emailcheck']);
$date = date("Y-m-d");
if($submit)
{
//check for existence
if($fname&&$lname&&$usernamereg&&$passwordreg&&$email&&$emailcheck)
{
//encrypt password
$password = md5($passwordreg);
if(strlen($usernamereg)>25)
{
echo "Username must be 25 characters or less.";
}
else
{
//checks password length
if(strlen($passwordreg)<6)
{
echo "Passwords must be atleast 6 characters long";
}
else
{
if($email!=$emailcheck)
{
echo "emails to not match";
}
else
{
//open database
$connect = mysql_connect("localhost","root","clandestine");
mysql_select_db("user_db"); //selects database
$queryreg = mysql_query("INSERT INTO users VALUES('','$date','$fname','$lname','$usernamereg','$passwordreg','$email','$emailcheck'");
echo "You have been registered!";
}
}
}
}
else
echo "Please fill in <b>all</b> fields!";
Try assigning the columns in the INSERT query.
$queryreg = mysql_query("INSERT INTO users (`randomField`, `date`, `first_name`, `last_name`, `username`, `password`, `email`, `email_check`) VALUES ('','$date','$fname','$lname','$usernamereg','$passwordreg','$email','$emailcheck'");
What is the first column supposed to be?
Have you done any sanity checking? (ie, printing test data to the screen at certain points in the code to make sure your IF statements are evaluating to true?
Additionally, try saving your INSERT query as a variable string:
$query = "INSERT INTO.............";
and then printing it to the screen. Copy and paste that query into PHPMyAdmin (if you have access to it) and see if there are any errors with your statement. PMA will tell you what errors there are, if any.
EDIT: Also, please don't ever MD5 a password or other highly sensitive data. Use a secure algorithm and salt the password. If you're unsure of what this all means:
refer to this link
What do you get if you do:
$query = "INSERT INTO users
(date, first_name, last_name, username, password, email, email_check)
VALUES
('$date','$fname','$lname','$usernamereg','$passwordreg','$email','$emailcheck')";
mysql_query($query)or die('Error: <br />'.$query.'<br />'.mysql_error());
Note the removal of the backticks was just to simplify the code. It's correct to leave them in but with no spaces etc in your column names it should work anyway. Oh, and this is NOT good practice for production, of course. Just really clear debug.

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). "'");

Form processing causing apache to crash?

I use the following code to register users on my site. The problem is that when a user registers apache doesn't respond and crashes.
Is there a break in my code or something I am doing wrong????
<?php
include ('../includes/db_connect.php');
$firstname = $_POST['firstname'];
$email = $_POST['email'];
$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);
//include 'register.html';
exit();
}
// lf no errors present with the username
// use a query to insert the data into the database.
$query = "INSERT INTO users (firstname, email, username, password)
VALUES('$firstname', '$email', '$username', '$password')";
mysql_query($query) or die(mysql_error());
mysql_close();
echo "You have successfully Registered";
// 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.";
?>
this script will NOT cause apache to die. on this side theres nothing wrong with it.
however i dont know whats in db_connect.php
the mailing is deactivated, this indeed could take a very long time if the server settings are not correctly. e.g. if the server cant find its fully qualified domain name as your comments suggests.
do you have a session active? this could explain why you cant access any website while the other one is still running and sending the mail and it may look to you like apache crashed.
because you didnt call session_write_close and only once session can be active for writing at a time.
whats definately wrong is the vulnerability to mysql injection.
you absolutely need to change your variables the following way:
$firstname = mysql_real_escape_string($_POST['firstname']);
$email = mysql_real_escape_string($_POST['email']);
$username = mysql_real_escape_string($_POST['username']);
furthermore i would recommend just having a unique que on username and try the insert and see whether you get an error or if you get an mysq_insert_id. let mysql do the job.
but your check is fine too.. but you should have a constraint in the database too, just as a precaution.
and you should trim your values and maby allow only certain chars, its annoying if a username on a website is &%DTRFG$Ä←↓ff

Categories