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
Related
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);
}
}
}
I have a change password script which is supposed to reset a users password with the values they provide assuming they match however this script is breaking something as users are not able to login with the password they provide to the script.
I'm not sure what is wrong as I also have an add_user script which is what I use to create the user accounts. The code to generate the password (hash) is the same and the data is successfully being put into the DB so I really don't know what is causing the problem. I'm guessing it has something to do with the data being provided prior to PHP hashing it thus in the DB it looks like it all went well as it's already hashed but I'm guessing if I was storing in plaintext it wouldn't be exactly the same as what the user entered otherwise the script would be working...
I've been working on the site all day so I'm really struggling to spot the error here.
I think my script used to work as this is the first I'm noticing the issue however I don't remember making any changes to this script in particular so cannot figure out why it would suddenly stop working.
session_start();
define('MyConst', TRUE);
include "includes/server.php";
if (!(isset($_SESSION['name']) && $_SESSION['name'] != ''))
{
header("location:login.php");
}
$con = mysqli_connect($DB_HOST, $DB_USER, $DB_PASS, $DB_NAME) or die(mysqli_error($con));
$password1 = mysqli_real_escape_string($con, $_POST['newPassword']);
$password2 = mysqli_real_escape_string($con, $_POST['confirmPassword']);
$username = mysqli_real_escape_string($con, $_SESSION['name']);
$passwordhashed = password_hash("$password1", PASSWORD_DEFAULT);
if ($password1 <> $password2)
{
echo "your passwords do not match";
$referrer = $_SERVER['HTTP_REFERER'];
header ("Refresh: 2;URL='$referrer'");
}
else if (mysqli_query($con, "UPDATE accounts SET password='$passwordhashed' WHERE username='$username'"))
{
echo "You have successfully changed your password.";
$referrer = $_SERVER['HTTP_REFERER'];
header ("Refresh: 2;URL='$referrer'");
}
else
{
mysqli_error($con);
}
mysqli_close($con);
Expected to check that passwords match and echo "You have successfully changed your password" if the change was successful and then redirect.
The form page was missing a method as I had forgotten to add one in so it was defaulting to _GET when the rest of the script was referencing _POST.
Fix was simply adding method as post.
I've got email function setup and working by setting the code to email a specific email address. However, with this is that it goes to the same email address everytime the submit button is pressed based on the data entered in a text box who the mail comes from.
However, I want to change it so that when a user enters their username in the username box it checks my database table for that username and checks their email address and emails them all the information set for that user.
The code i'm using is ;
$username = $_POST['username'];
$my_query="SELECT * from loanusers where username = '$username'";
$result= mysqli_query($connection, $my_query);
$to = $myrow["emailaddess"];
$subject = 'CSG - Forgotten Password';
$sender = 'CSGLoanSystem#mail.com';
$password = $myrow["password"];
$admin = 'CSGLoanSystem Admin Team';
$body = <<< EMAIL
Hi {$username}, You have recently requested a notification of your password.
The Password registered with account {$username} is $password.
Thanks - {$admin}
EMAIL;
$header = "From:" . $sender;
if ($result):
mail($to, $subject, $body, $header);
$feedback = 'Email Sent';
endif;
At the moment when the submit button is pressed, the page refreshes but nothing actually happens and no email is received at the expected email address?
Pointing to the right direction:
Read up on MySQL and PDO. Also Read up on prepared statements and parameter binding.
Elaborating on the directions given:
There are many ways to connect to a database, and there are many different databases available. One popular database software is called MySQL, and the coding method that is most recommended to connect to that database is PDO for reasons such as having better methods for preventing security breaches.
You can find a lot of online tutorials on how to connect to a database, so I won't go into that, though I will however give you an example of a query you could use to do your email searching, and also I'll include prepared statements and parameter binding since these two details are often misunderstood by a lot of programmers.
If you have the following table:
users
______________________________
| username | email |
|------------+-----------------|
| john44 | abc#gmail.com |
|------------+-----------------|
| adam11 | 123#gmail.com |
|------------+-----------------|
the following code would allow you to retrieve john44's email:
$username = $_POST['username'];//getting the username written in the form
$sql = "SELECT email FROM users WHERE username = ?";
$stmt = $conn->prepare($sql);
$stmt->execute([$username]);
$result = $stmt->fetch(PDO::FETCH_ASSOC);
//here I'm just outputting the obtained email for you to see
//it works, however you would then use the email saved in
//$result['email'] whichever way you want.
echo "email = {$result['email']}<br>";
Edited:
After you edited your code, I noticed you are not fetching the information you queried. Insert the following code after line $result= mysqli_query($connection, $my_query);:
$myrow = mysqli_fetch_assoc($result);
Problem has been solved
I have created a form that processes the changing of user information from the admin side e.g. the admin changes a user's username and/or email. I am having trouble processing multiple queries.
For example, if the admin changes the username, the query works. If the admin changes the email address, the query works. But if the admin changes the username and email at the same time through the form then only the username changes.
Any ideas? I will submit my code but I will change variables for security reasons etc. Also, anything in capitals has been changed for security reasons. The code is all correct for each individual function because as I said, if I ONLY change the email, it works and actually changes. But if I change the username AND email, only the username will change despite the fact the email query runs and it echo's the email has been changed!
Also, it is worth noting that all of the fields e.g. username field and email field are part of one form that submits to one page.
if (isset($_POST['SUBMIT_BUTTON_PRESSED'])) {
//Gather all inputs from the form and sanitise it.
//REMOVED FOR SECURITY REASONS.
if($USERNAME_NEW != "") {
if($USERNAME_NEW == $CURRENT_USERNAME) {
echo "You have entered the username you are already using. Please enter a different username.";
} else {
$CHECK_USERNAME = "SELECT USERNAME_ROW FROM USERS_TABLE WHERE username='$USERNAME_NEW'";
$RUN_QUERY = mysqli_query($CONNECTION INFO, $CHECK_USERNAME);
$RESULT = mysqli_num_rows($RUN_QUERY);
if($RESULT > 0) {
echo "That username already exists. You cannot use that username again. Please enter another username.";
} else {
$editing_username = true;
$USERNAME = $NEW_USERNAME; //NOT NEEDED BUT IT STILL WORKS
$THE_SQL_QUERY = "UPDATE USER_TABLE SET username='$USERNAME' WHERE username='$ORIGINAL USERNAME'";
$RUN_THIS_QUERY= mysqli_query($CONNECTION INFO, $THE_SQL_QUERY);
echo "The user's username has been changed to: ". $USERNAME;
}
}
}
if($EMAIL != "") {
if($EMAIL == $CURRENT_EMAIL) {
echo "You have entered the same email address to the one you are already using. Please enter a different email address.";
} else {
$CHECK_EMAIL = "SELECT USERS_EMAIL FROM USER_TABLE WHERE username='$USER'";
$CHECK_EMAIL_QUERY = mysqli_query($CONNECTION_INFO, $CHECK_EMAIL);
$RESULT = mysqli_num_rows($CHECK_EMAIL_QUERY);
if($RESULT > 0) {
echo "That email already exists. You cannot use that username again. Please enter another username.";
} else {
$editing_email = true;
$THE_NEW_EMAIL = $FINAL_EMAIL_THING; // AGAIN NOT NEEDED BUT STILL WORKS
$THE_SQL= "UPDATE USER_TABLE SET USER_EMAIL='$EMAIL' WHERE username='$USER' LIMIT 1"; // REMOVED THE LIMIT 1, STILL DOESN'T WORK
$RUN_THIS_QUERY = mysqli_query($CONNECTION, $THE_SQL);
if($RUN_THIS_QUERY) {
echo "The user's email has been changed."; // EVEN WHEN BOTH FIELDS ARE SUBMITTED THIS WORKS SO THE QUERY IS RUNNING BUT THE EMAIL DOESN'T CHANGE
}
}
}
}
Thanks for the help! Also, no un-witty remarks about how my question is structured etc. because I don't care to be honest. I just want this code working to be honest because I've been working on it for a while. This may be something simple or I might be using the wrong approach for this type of form submission.
Remember: THIS CODE DOES WORK WHEN I SUBMIT EACH FIELD SEPARATELY!
Its very hard to figure out as you are not producing the real code.
I think you have missed something here.
As you are using USER_NAME as key in the SQL's, make sure that you are using the updated username in the second sets of SQL (to update the email) as they are already replaced by the first SQL.
And there is no security risk while showing your codes snippets to someone else. Hide only the username/passwords or Identities. :)
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). "'");