I am creating a forgotten password page and will be emailing a temporary password to the user so they can log in and reset their password.
What should I take into account when creating the password, what is the best method.
An idea I had is something like: $temporarypassword = sha1($_SERVER['REMOTE_ADDR'])
In an attempt to only allow them to login from the ip address where they requested the temp password. What is the best way to do this??
Code so far:
if(strpos($_SERVER['HTTP_REFERER'],'domain.com') && ($_POST['forgotpasstoken'] == sha1($_SESSION['token'].'forgotpassword'))){
if(isset($_POST['forgotemail']) && !empty($_POST['forgotemail'])){
$email = mysql_escape_string(trim($_POST['forgotemail']));
if(filter_var($email, FILTER_VALIDATE_EMAIL) === FALSE){
echo '<div class="error">Please enter a valid email address.</div>';
} else {
$sql = "SELECT email FROM users WHERE email = '$email' LIMIT 1";
$res = mysql_query($sql) or die(mysql_error());
if (mysql_num_rows($res) > 0) {
//If email/user exists
$temporarypassword = sha1($_SERVER['REMOTE_ADDR'])
//EMAIL PASSWORD HERE
echo '<div class="success">A temporary recovery password has been emailed to you.</div>';
//If email/user exits
} else {
echo '<div class="error">This email is not registered.</div>';
}
}
} else {
echo '<div class="error">Please enter an email address.</div>';
}
}
Use just a random string: it's more than likely that user tries to log in from e.g. iPhone, fails, requests a new password, and only opens the link when he's at his home PC. IPs are different, device is different, everything's different.
If you're emailing the password, there is no way to make it fully secure. Email is transmitted in plain text. And like alf said, the user may reset the password from a different IP address than the one they requested it from.
One option would be to create a random string, then display half of it on the password reset page (after the reset request is made) and half of the string in the email. Then require the user to enter both halves in a form before letting them choose a new password.
Related
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. :)
What im basically trying to do is to confirm the identity of the user by using the mail address then Do certain database operation if the identity is verified.
I want to generate a confirmation code and send to the email address in the form of a URL.
But i do not want to maintain a database for the confirmation codes.How can i do this using encryption.Any Ideas?
it should look like:
<?php
$salt = "this is a secret key!!!";
if(isset($_GET["confirm"]) && isset($_GET["email"])){
$confirm = $_GET["confirm"];
$to_email = $_GET["email"];
if(sha1($salt.$to_email) == $confirm){
// this mail is confirmed, now do some db work
// update_db ... ();
}else{
die("error: mail not confirmed");
}
}elseif(isset($_GET["email"])){
$to_email = $_GET["email"];
$confirm_link = $_SERVER["PHP_SELF"]."?confirm=".urlencode(sha1($salt.$to_email))."&mail=".urlencode($to_email);
$msg = "to confirm ... click the link: \n ".$confirm_link;
mail($to_email,"pls. confirm your mail",$msg);
}else{
die("error message");
}
?>
You could Hash the email address in question with some secret salt and make that the token in the link. Then when you're verifying it, repeat that same process.
Best way of that is having a varchar field in your database named "activation".
So you can keep "confirmation code" there. When user has activated his account you will update it to "1". So if the field is "1"; User has activated his account. Otherwise there will be still confirmation code there and user's account is not activated. So there will be at least one column for activation process.
When a user forgets his password, there is an email sent to his email account with a link and token (unique) to resetpassword.php
When the authentication is correct then he is able to change the password. My question is how can this happen?
The quick and easy way is to email him a new password and let him change it through his CP, but is this a good user-experience?
$result = mysql_query("SELECT member_id FROM members WHERE forgotpass='$token'");
if(mysql_num_rows($result) == 1) {
WHAT GOES HERE?
}
else {
die("Query failed");
}
WHAT GOES HERE?
there should be something like
echo 'Your password was mailed to you';
mysql_query("UPDATE members SET password = '".$random_hashed_string."' WHERE forgotpass='$token'");
mail($to, $subject, $message." password:".$random_hashed_string, "From: support#support.com");
You will need to create a form to allow the user to select a new password. The form's action will update the database user record's password field. This will probably be a separate process, but your WHAT GOES HERE? will be an HTML form.
ive created a form and im using php to check if the username exists in the database, if it is then the form will not submit and echo an alter that the username has already been taken, if i fill the form out and submit it with a name thatn i know is in the database, i get the error saying that the username already exists, but i also get the text that says.. Thank you for signing up
basically its showing the error correctly but it still submitting all the for data to the database
can you see anything in my code thats causing this??
//Check to see if the username is already taken
$query = "SELECT * FROM clients";
$result = mysql_query($query) or die(mysql_error()); // Get an array with the clients
while($row = mysql_fetch_array($result)){ // For each instance, check the username
if($row["username"] == $username){
$usernametaken = true;
}else{$usernametaken = false;}
}
// If the username is invalid, tell the user.
// Or else if the password is invalid, tell the user.
// Or else if the email or PayPal address is invalid, tell the user.
// Else, if everything is ok, insert the data into the database and tell
// the user they’ve successfully signed up.
if($usernametaken)
{
echo "That username has been taken.";
}
if(!preg_match('/^[a-zA-Z0-9]+$/', $username ))// If our username is invalid
{
echo "The username can only contain letters or numbers"; // Tell the user
}
else if(!preg_match('/^[a-zA_Z0-9]+$/', $password ))// If our password is invalid
{
echo "The password can only contain letters or numbers"; // Tell the user
}
// If our email or PayPal addresses are invalid
else if(!preg_match("/^[_a-z0-9-]+(.[_a-z0-9-]+)*#[a-z0-9-]+(.[a-z0-9-]+)*(.[a-z]{2,3})$/", $email))
{
return "The email or PayPal address you entered is invalid."; // Tell the user
}
else{
// Inserts the data into the database
$result = mysql_query("INSERT INTO clients (client_ID, username, password, email, paypal)"."VALUES ('', '$username', '$pw', '$email', '$paypal')");
echo "Thank you for signing up.";
}
?>
You need to break out of your function if the username is no good. You could add an else if before the preg match if you don't want your last line to run. Basically your program flow is
//if username taken
//if bunch of cases
//else add client
There is nothing separating your two if statements.
Your SQL statement is a bear too. You are looping through every client in your db to see if it is a duplicate. Just add a where statement
$query = "SELECT * FROM clients WHERE clientName = '$clientName'";
You don't have anything to tell the script to stop executing if it finds that the username is taken. Restructure your if-else statement like this:
if($usernametaken)
{
echo "That username has been taken.";
} else {
// If username is not taken...
}
Instead of using several else ifs may I recommend using exceptions for this situation.
Demonstration:
<?php
try
{
if ($usernametaken) throw new Exception('That username has been taken.');
// If we've reached here we know data has been checked properly
$result = mysql_query("INSERT INTO clients (client_ID, username, password, email, paypal)"."VALUES ('', '$username', '$pw', '$email', '$paypal')");
echo "Thank you for signing up.";
}
catch (Exception $e)
{
echo $e->getMessage();
}
?>
I've created a code to change a password. Now it seem contain an error.
When I fill in the form to change password, and click save the error message:
You forgot enter your userid!
Please try again.
I really don’t know what the error message means. Please guys. Help me fix it.
Here's is the code:
<?php # change password.php
//set the page title and include the html header.
$page_title = 'Change Your Password';
//include('templates/header.inc');
if(isset($_POST['submit'])){//handle the form
require_once('connectioncomplaint.php');//connect to the db.
//include "connectioncomplaint.php";
//create a function for escaping the data.
function escape_data($data){
global $dbc;//need the connection.
if(ini_get('magic_quotes_gpc')){
$data=stripslashes($data);
}
return mysql_real_escape_string($data);
}//end function
$message=NULL;//create the empty new variable.
//check for a username
if(empty($_POST['userid'])){
$u=FALSE;
$message .='<p> You forgot enter your userid!</p>';
}else{
$u=escape_data($_POST['userid']);
}
//check for existing password
if(empty($_POST['password'])){
$p=FALSE;
$message .='<p>You forgot to enter your existing password!</p>';
}else{
$p=escape_data($_POST['password']);
}
//check for a password and match againts the comfirmed password.
if(empty($_POST['password1'])) {
$np=FALSE;
$message .='<p> you forgot to enter your new password!</p>';
}else{
if($_POST['password1'] == $_POST['password2']){
$np=escape_data($_POST['password1']);
}else{
$np=FALSE;
$message .='<p> your new password did not match the confirmed new password!</p>';
}
}
if($u && $p && $np){//if everything's ok.
$query="SELECT userid FROM access WHERE (userid='$u' AND password=PASSWORD('$p'))";
$result=#mysql_query($query);
$num=mysql_num_rows($result);
if($num == 1){
$row=mysql_fetch_array($result, MYSQL_NUM);
//make the query
$query="UPDATE access SET password=PASSWORD('$np') WHERE userid=$row[0]";
$result=#mysql_query($query);//run the query.
if(mysql_affected_rows() == 1) {//if it run ok.
//send an email,if desired.
echo '<p><b>your password has been changed.</b></p>';
//include('templates/footer.inc');//include the HTML footer.
exit();//quit the script.
}else{//if it did not run OK.
$message= '<p>Your password could not be change due to a system error.We apolpgize for any inconvenience.</p><p>' .mysql_error() .'</p>';
}
}else{
$message= '<p> Your username and password do not match our records.</p>';
}
mysql_close();//close the database connection.
}else{
$message .='<p>Please try again.</p>';
}
}//end of the submit conditional.
//print the error message if there is one.
if(isset($message)){
echo'<font color="red">' , $message, '</font>';
}
?>
<form action="<?php echo $_SERVER['PHP_SELF']; ?>" method="post">
Please don't store the actual password in the database. Create a hash of the password and store it. When a user logs in, hash the incoming password and check if it matches the hashed password for the user. See http://phpsec.org/articles/2005/password-hashing.html for more info.
Also, it would be more secure to store the userid in the session and retrieve it from there rather than getting it from the form. Even if the input is hidden on the page there are any number of ways that it could be substituted. It leaves you with a small hole in the application where, if one user knows another user's id and password, they can change it in an undetectable fashion. That is, the password could be changed despite the fact that you have no record of that user having logged in. Even when getting the user id from the form (or the url), always check that the data they are operating on is their own, not someone else's unless, of course, they are a user with sufficient privileges.
It means that you didn't send along userid with your POST parameters. Presumably, your form didn't include an element with name userid. The error comes from this line:
if(empty($_POST['userid'])){
That error is displayed because of this test :
if(empty($_POST['userid'])){
$u=FALSE;
$message .='<p> You forgot enter your userid!</p>';
}
Which means the server doesn't receive a userid field from the form.
I'm guessing you should make sure there is such a field in your form -- and it'll have to contain the userid of the user for which you want to change the password.
Considering you probably don't want that field to be displayed, though, you'll use a hidden input :
<input type="hidden" name="userid"
value="<?php echo htmlspecialchars(HERE THE USERID); ?>" />
According to your code it means that the userid POST variable was empty. Verify the name of the field you use for it.