So, I've been trying to create a Signup/Login process using PHP and MySQL. I created a Signup form, and a handling page. Then I tred it out, set the email as a#a.com and password as MyPassword.
I then checked the database and got surprised. The email was correctly inputted, alright, but the password wasn't! It was one of the passwords that I used to test before, and it is a pretty personal one.
Every time I tried it again, the same thing happened. The password was always changed to my personal one whenever I signed up.
The problem is that, in my code, I don't have that personal password, anywhere. I only used it to test my signup flow once, and now it's stuck to my database!
Here, I registered using test credentials. The password is asd and it's obviously 3 letters long.
But when I check the database, I see the following. Even though I edited the password so you can't see it, it's still obvious it's more than 3 letters long.
Is this some kind of MySQL over-writing thing, that I just don't know about yet?
Here is the full code of the SignUp Page (Might be a little long, bear with me):
<?php
session_start();
$firstName = $_POST['firstName'];
$lastName = $_POST['lastName'];
$email = $_POST['signUpemail'];
$password = $_POST['signUppassword'];
include("mysql_base.php");
echo "Preparing MYSQL Statement...<br>";
echo "<script>";
echo "firstPart()";
echo "function firstPart() {";
echo "document.write('Starting to process MYSQL Statement...')";
echo "window.setTimeout(secondPart(),2000)";
echo "}";
echo "function secondPart() {";
echo "document.write('Starting to stop processing MSYQL Statement...')";
echo "}";
echo "</script>";
echo "Started to proccess...<br>";
$sql = "INSERT INTO pages_accounts (email, pass, firstname, lastname, confirm) VALUES ('".$email."','".$password."','".$firstName."','".$lastName."','0')";
if ($conn->query($sql) === true){
echo "<b>SIGNUP SUCCESS</b><br>";
echo "SUCH HAPPINESS. WOW. MMM.<br><br>";
echo "--Check your mail for a confirmation email. Check SPAM too!--";
$headers = "MIME-Version: 1.0" . "\r\n";
$headers .= "Content-type:text/html;charset=UTF-8" . "\r\n";
$headers .= 'From: FoxInFlame Pages<pages#foxinflame.tk>' . "\r\n";
$message = "
<html>
<body>
<center>
<div style='background-color:orange'><h1>Confirm your Account</h1><br><h3>At FoxInFlame Pages</h3></div>
You seem to have registered for an account at FoxInFlame Pages. Now please click on the following link to complete your registration, and start creating amazing websites!<br><a href='http://www.foxinflame.tk/pages/confirm.php?id=".$conn->insert_id."'>Click Here</a>
</center>
</body>
</html>
";
mail($email, "[CONFIRM] Account on FoxInFlame Pages", $message);
} else {
echo "MUCH SADNESS. SUCH DEPRESSION. FAIL ERROR. NO RETURN.";
echo "Error: ".$sql."<br>".$conn->error;
};
?>
Your problem will be in include("mysql_base.php");. That file will be setting $password for it's own internal use, which is overwriting the $password variable that you get from $_POST;
2 options to get around this:
1 - Open the database connection first.
<?php
session_start();
include("mysql_base.php");
$firstName = $_POST['firstName'];
$lastName = $_POST['lastName'];
$email = $_POST['signUpemail'];
$password = $_POST['signUppassword'];
2 - Use different variable names:
<?php
session_start();
include("mysql_base.php");
$signup_firstName = $_POST['firstName'];
$signup_lastName = $_POST['lastName'];
$signup_email = $_POST['signUpemail'];
$signup_password = $_POST['signUppassword'];
Aside from this, the password field on the sign up page doesn't have name="signUppassword", and you have no SQL Injection protection.
On your page I see:
<input style="color:white" type="password" name="password" required="" autocomplete="off">
So your input name is password
But in your code you are trying to get signUppassword:
$password = $_POST['signUppassword'];
Do you have some transformation somewhere ? javascript?
Related
I am trying to create a forgot password page for the user in PHP but when I enter the code the page just reloads and nothing else happens . No errors nothing .
if($submit){
$email = mysqli_real_escape_string($conn, $_POST["email"]);
$submit = $_POST['submit'];
$email_check = mysqli_query($conn ,"SELECT * FROM users WHERE email='" . $email. "'");
$count = mysqli_num_rows($email_check);
if($count != 0 ){
// generate a new password
$random = rand(72891, 92729);
$new_password = $random;
$email_password = $new_password;
$new_password = password_hash($new_password, PASSWORD_BCRYPT, array('cost' => 14));
$new_password = password_hash($new_password);
mysqli_query("update users set pw='" . $new_password. "' WHERE email='" . $email. "'");
$subject = "Login information";
$message = "Your password has been changed to $email_password";
$from = "From: example.me";
mail($email, $subject, $message, $from);
echo "Your new password has been sent to you";
} else {
echo"This email does not exists";
}
}
I will tell you exactly what is going on with your code here.
Part 1:
if($submit){
$email = mysqli_real_escape_string($conn, $_POST["email"]);
$submit = $_POST['submit'];
$submit = $_POST['submit']; is assigned after your opening if($submit).
Result with error reporting: Undefined submit variable.
Part 2:
$new_password = password_hash($new_password, PASSWORD_BCRYPT, array('cost' => 14));
$new_password = password_hash($new_password);
You're trying to double hash which won't give you any added benefits and will also fail when trying to verify it later. What happened here is that the second one failed and shouldn't even be used at all.
Why did it fail? Because, it's missing a parameter.
Result:
Warning: password_hash() expects at least 2 parameters, 1 given in /path/to/file.php on line x
Added result: An empty password row (when the UPDATE happens. See "Part 3").
Part 3:
mysqli_query("update users set pw='" . $new_password. "' WHERE email='" . $email. "'");
The query doesn't contain a database connection for it.
Result:
Warning: mysqli_query() expects at least 2 parameters, 1 given in /path/to/file.php on line x
In regards to your variables and the connection API used is unknown, so you will have to make sure that you are using the same MySQL API to connect with, and that your variables and POST arrays contain values.
Error reporting will help you, as will checking for errors on the query.
References:
http://php.net/manual/en/function.error-reporting.php
http://php.net/manual/en/mysqli.error.php
Final notes:
Use a prepared statement instead, it's much safer
https://en.wikipedia.org/wiki/Prepared_statement
Also; you should let the user choose their own password in a reset with a unique/one time token and hash it "once", not twice and shouldn't be mailed their password and for a lot of reasons. This is best common practice. If the user's email account ever gets compromised and they haven't deleted the email containing their login password, then they are at risk in having their login account also being compromised.
$submit is not declared until after the validation of your if statement.
Validate using another variable. Good place to start is to check and see if $_POST is submitted
if ($_SERVER['REQUEST_METHOD'] == 'POST')
To email the password change
$message = "Your password has been changed to $email_password";
to
$message = "Your password has been changed to {$email_password}";
The password stored in the DB has been hashed twice. Remove
$new_password = password_hash($new_password);
The SQL needs to be executed to update the password hash in the database.
$sql = "update users set pw='" . $new_password. "' WHERE email='" . $email. "'";
if (mysqli_query($conn, $sql)) {
echo "Password updated successfully";
} else {
echo "Error updating record: " . mysqli_error($conn);
}
mysqli_close($conn);
You're testing for $submit but defining $submit inside of the test, so $submit likely isn't evaluating as true.
Try changing the outer if ($submit) to if (!empty($_POST))
Am creating an application... everything is fine so far. In my registration system have used prepared statement and password hashing and have also try to validate user input in my form fields as well. In order for this system to be completed i need to create a forgot password system which means user can request for new password.
What have done is i have a testing site with all the files, which means i can test if works before adding it to the production site.
With the forgot password have used mysqli once everything is working fine i will then update to prepared, because am still learning prepared statement and doing it this way help me understand so don't judge.
The problem am having with my forgot password is the password is not updating once change. see this screenshot: http://prntscr.com/d5hage
Also as mentioned above have used http://prntscr.com/d5hbg1 in my register and verify in my log-in. But how do used the hashing in my forgot password or how do i update it. In my code below have used md5 which am aware is broken. Please all my coding below.
Reset_Password.php
<?php
// include connection
require_once('include/connection.php');
if(isset($_POST['submit'])){
$user_id = base64_decode($_GET['encrypt']);
$passnew = password_hash($password, $_POST['new_password'], PASSWORD_BCRYPT, array( 'cost' => 12 ) );
$sql = "UPDATE `olami560_test`.`user` SET `password` =? WHERE `user`.`id` =?";
$stmt = $con->prepare($sql);
$stmt->bind_param('si',$passnew, $user_id);
$stmt->execute();
if ($stmt->errno) {
echo "FAILURE!!! " . $stmt->error;
}
else echo "Password Changed Successfully.Click on link to login <a href='http://www.olaskee.co.uk/project/allocation/progress/index.php'>Login</a>{$stmt->affected_rows} rows";
$stmt->close();
}
?>
<form method="post" action="<?php echo $_SERVER['HTTP_REFERER']; ?>" >
<label>New Password</label>
<input type="password" name="new_password"/>
<input type="submit" name="submit" value="Reset" />
</form>
forgot_password.php
<?php
// include connection
require_once('include/connection.php');
if(isset($_GET) && !empty($_GET['email'])){
$email = mysqli_real_escape_string($con,$_GET['email']);
$query = "SELECT id
FROM `user`
WHERE `user_name` LIKE '".$email."'
OR `email` LIKE '".$email."'";
$result = mysqli_query($con,$query);
$Results = mysqli_fetch_array($result);
if(count($Results)>=1)
{
$query2 = "SELECT email
FROM `user`
WHERE `user_name` LIKE '".$email."'
OR `email` LIKE '".$email."'";
$result2 = mysqli_query($con,$query2);
$emailvalue = mysqli_fetch_array($result2);
//$token = md5(uniqid(rand(),true));
//$encrypt = md5($Results['id']);
$encrypt = base64_encode($Results['id']);
$message = "Your password reset link send to your e-mail address.";
$to = $emailvalue['email'];
$subject="Forget Password";
$from = 'leksmaster#gmail.com';
$body= 'Hi, <br/> User <br/>You Requested for Reset Password. <br><br>http://www.olaskee.co.uk/project/allocation/tms/reset_password.php?token='.$token.'&encrypt='.$encrypt.'&action=reset<br/> <br/>--<br>.olaskee<br>';
$headers = "From: " . strip_tags($from) . "\r\n";
$headers .= "Reply-To: ". strip_tags($from) . "\r\n";
$headers .= "MIME-Version: 1.0\r\n";
$headers .= "Content-Type: text/html; charset=ISO-8859-1\r\n";
mail($to,$subject,$body,$headers);
echo $message;
}
else
{
$message = "Account not found please signup now!!";
echo $message;
}
}
?>
I hope have provide enough explanation for you to understand. Thanks any input.
ok, looking through the code there are a few things I think you need to look at.
On the form change this
<form method="post" action="<?php echo $_SERVER['HTTP_REFERER']; ?>" >
to
<form method="post" action="" >
This should submit the form to itself.
The hashing really needs to be password_hash() use the following and it will get you started
$passnew = password_hash( $password, $_POST['new_password'], PASSWORD_BCRYPT, array( 'cost' => 12 ) );
On the form for resetting the password it is a good idea to have the user input the new password twice, that way you can check if they have repeated the password correctly.
if( $_POST[ 'pass1' ] == $_POST[ 'pass2' ] ) // Process else error
In your forgot_password.php file you are calling the same sql statement twice. Call it once, check if the row count is greater then one, if it is use the data from within the result, no need to call it again to do the same thing.
Hopefully this will get you going, have a good day.
So I've sent a link after registration to Verify an account, the link contains the users email address and a 32 character code for example:
$to = $email;
$subject = 'Signup | Verification';
$message = '
Thanks for signing up!
Your account has been created, you can login with the following credentials after you have activated your account by pressing the url below.
------------------------
Username: '.$username.'
Password: '.$password.'
------------------------
Please click this link to activate your account:
localhost:8888/website/verify.php?email='.$email.'&hash='.$hash.'
';
$headers = 'From:myemail#email.com' . "\r\n";
mail($to, $subject, $message, $headers);
That all seems to work fine I'm receiving the email with a link like this:
http://localhost:8888/website/verify.php?email=myemail#email.com&hash=fe646d38bc2145ca6c3cf77d52820cd0
The problem comes when I follow the link and try to activate the account. It takes me to Verify.php fine but I keep getting Invalid Approach and I'm unable to set Validation to 1.
<?php include "includes/base.php"; ?>
<?php
if(isset($_GET['Email']) && !empty($_GET['Email']) AND isset($_GET['Hash']) && !empty($_GET['Hash'])){
$email = mysql_escape_string($_GET['Email']);
$hash = mysql_escape_string($_GET['Hash']);
$search = mysql_query("SELECT Email, Hash, Validation FROM users WHERE Email = '".$email."' AND Hash = '".$hash."' AND Validation = 0") or die(mysql_error());
$match = mysql_num_rows($search);
if($match > 0){
mysql_query("UPDATE users SET Validation = 1 WHERE Email = '".$email."' AND Hash = '".$hash."' AND Validation = 0") or die(mysql_error());
echo "Your account has been activated, you can now login";
}else{
echo "The url is either invalid or you already have activated your account.";
}
}else{
echo "Invalid approach, please use the link that has been sent to your email.";
}
?>
1) this code is unsecure as it has SQL injection problem. Use prepared statements
Please keep in mind that mysql_* functions are no longer supported and they are depriated
2) Regarding your code I found that your GET request has 'email' and 'hash' all lowercase, but in PHP code you use $_GET['Email'] and $_GET['Hash'].
You need to change this:
if(isset($_GET['Email']) && !empty($_GET['Email']) AND isset($_GET['Hash']) && !empty($_GET['Hash'])){
$email = mysql_escape_string($_GET['Email']);
$hash = mysql_escape_string($_GET['Hash']);
To this
if(isset($_GET['email']) && !empty($_GET['email']) AND isset($_GET['eash']) && !empty($_GET['eash'])){
$email = mysql_escape_string($_GET['email']);
$hash = mysql_escape_string($_GET['eash']);
or change your GET request to the next one:
http://localhost:8888/website/verify.php?Email=myemail#email.com&Hash=fe646d38bc2145ca6c3cf77d52820cd0
Change Hash to hash & Email to email. (Capitalized, but not in link that you send)
Also, your code is prone to sql injection attack as you are directly using the values in the url to query your database. Please use mysql_real_escape_string and perform some sanity checks before making the query.
there's capitals in the PHP whereas there are none in the link
$_GET['Email']
verify.php?email=myemail#email.com
Hey guys, I have this sign up script and I'm using mysql_real_escape_string .I know prepared statements are safer but I'm just not experienced enough to use them, I just can't figure out how. Anyway here's the script:
<?php
$username=mysql_real_escape_string($_POST['username']);
$password=sha1($_POST['password']);
$password2=sha1($_POST['password_confirmation']);
$passcheck=$_POST['password'];
$todo=mysql_real_escape_string($_POST['todo']);
$email=mysql_real_escape_string($_POST['email']);
$fname=mysql_real_escape_string($_POST['fname']);
$lname=mysql_real_escape_string($_POST['lname']);
$gender=$_POST['gender'];
$class=$_POST['class'];
$section=$_POST['section'];
if(isset($todo) and $todo=="post"){
$status = "OK";
$msg="";
}
if(!isset($username) OR strlen($username) <3){
$msg=$msg."Username should be equal to or more than 3 characters long.<BR/>";
$status= "NOTOK";
}
if(mysql_num_rows(mysql_query("SELECT username FROM users WHERE username = '$username'"))){
$msg=$msg."Username already exists. Please try another one.<BR/>";
$status= "NOTOK";
}
if(mysql_num_rows(mysql_query("SELECT email FROM users WHERE email = '$email'"))){
$msg=$msg."E-mail is already in use. Please try again.<BR/>";
$status= "NOTOK";
}
if ( strlen($passcheck) < 3 ){
$msg=$msg."Password must be more than 3 charactors long.<BR/>";
$status= "NOTOK";
}
if ( $password <> $password2 ){
$msg=$msg."Passwords are not identical.<BR/>";
$status= "NOTOK";
}
if(!eregi("^[_a-z0-9-]+(\.[_a-z0-9-]+)*#[a-z0-9-]+(\.[a-z0-9-]+)*(\.[a-z]{2,3})$", $email)){
$msg=$msg."The email is not a valid email.<br/>";
$status="NOTOK";
}
if($status=="NOTOK"){
echo '<div class="statusmsg">'.$msg.'<br/><input class="submitButton" type="button" value="Retry" onClick="location.href='."'signup.php'\"></div>";
}
else {
$hash = md5( rand(0,1000) );
$hash = mysql_real_escape_string($hash);
if(mysql_query("insert into users(username,password,email,fname,lname,hash,gender,class,section) values('$username','$password','$email','$fname','$lname','$hash','$gender','$class','$section')")or die (mysql_error ())){
echo '<div class="statusmsg">Welcome, You have successfully signed up. Please check the verification e-mail sent to you.</div>';
$to = $email;
$subject = 'Signup | Verification';
$message = '
Thanks for signing up!
Your account has been created, you can login with the following credentials after you have activated your account by pressing the url below.
------------------------
Username: '.$username.'
------------------------
Please click this link to activate your account:
<div id="header">
<h3>JMToday > Sign up</h3>
</div>
http://www.JMtoday.com/verification.php?email='.$email.'&hash='.$hash.'
';
$headers = 'From:noreply#JMtoday.com' . "\r\n";
mail($to, $subject, $message, $headers);
}
else {
echo "Database problem, please contact site admin";
}
}
?>
The user will never see the "database problem" message, as the script will die() out if the query fails. As well, you're embedding HTML into the message, but are not building a proper HTML-format email. Some mail clients may be smart enough to figure out there's HTML and render it as such, but that's just luck.
The hash you generate is limited to generating only 1001 hashes. Given the birthday paradox, after 38 people sign up, the odds of a collision are 50%. After 100 people, the odds are 99.29%. Instead of hashing a random number, do something like:
$hash = md5(serialize($_POST) . $some_other_stuff_in_case_POST_is_empty);
i have a PHP contact form that submits data, and an email...:
<?php
$dbh=mysql_connect ("localhost", "username", "password") or die ('I cannot connect to the database because: ' . mysql_error());
mysql_select_db ("guest");
if (isset($_POST['submit'])) {
if (!$_POST['name'] | !$_POST['email'])
{
echo"<div class='error'>Error<br />Please provide your Name and Email Address so we may properly contact you.</div>";
}
else
{
$age = $_POST['age'];
$name = $_POST['name'];
$gender = $_POST['gender'];
$email = $_POST['email'];
$phone = $_POST['phone'];
$comments = $_POST['comments'];
$query = "INSERT INTO contact_us (age,name,gender,email,phone,comments)
VALUES ('$age','$name','$gender','$email','$phone','$comments')";
mysql_query($query);
mysql_close();
$yoursite = "Mysite ";
$youremail = $email;
$subject = "Website Guest Contact Us Form";
$message = "$name would like you to contact them
Contact PH: $phone
Email: $email
Age: $age
Gender: $gender
Comments: $comments";
$email2 = "my#email.com";
mail($email2, $subject, $message, "From: $email");
echo"<div class='thankyou'>Thank you for contacting us,<br /> we will respond as soon as we can.</div>";
}
}
?>
The email is coming through fine, but the data is not storing the dbase... am i missing something?
Its the same script as i use on another contact us page, only difference is instead of parsing the data on teh same page, i now send this data to a "thankyou.php" page... i tried changing $_POST to $_GET but that killed the page... what am i doing wrong?
First of all, you must escape your data before injecting them in your SQL query.
This can be done using the mysql_real_escape_string function, like this :
$name = mysql_real_escape_string($_POST['name']);
// ... same for other fields that contain strings
$comments = mysql_real_escape_string($_POST['comments']);
This will ensure that quotes in your data are escaped, and don't mess with the ones that are arround the fields' data in the SQL query, first.
And, second, this will help you prevent SQL Injections.
Also, in case of an error during the execution of a query, mysql_query will return false -- which means you should test the value returned by that function -- to possibly log the cause of the error :
$result = mysql_query($query);
if ($result === false) {
// An error has occured...
echo mysql_error();
}
Note : here, I just displayed the error message -- but you should instead log the error somewhere (to a file, for instance), before putting your application to production : your users don't need (nor want) to see any technical error message !
Check the result from mysql_query(...) to see if it failed or not. If it didn't fail, MySQL should definitely have stored the information for you.