0

so I'm trying to make a set a new password page

I have a forgot password page where I'm sending an email to the user by generating a token which will help me to make the link usable only once, once the password was generated the token will become NULL

this is the template of the link

$url = "..../test.php?token=$str&email=$email";

I get the link on my email then when I open the page I get the error if the token is not ok

<form action="test.php" method="post" class="login100-form validate-form"> 

    <div class="wrap-input100 validate-input m-b-50" data-validate="Enter password">
        <input type="password" class="input100"   name="lalala"  required/> 
        <span class="focus-input100" data-placeholder="Parola"></span>
    </div>

    <?php

    ini_set("display_errors", "1");
    error_reporting(E_ALL);

    if (isset($_GET["token"]) && isset($_GET["email"])) {
        $connection = new mysqli('myhostr.com', 'xxxxxxxxx', 'xxxxxxxxx', 'xxxxxx');

        $email = $connection->real_escape_string($_GET["email"]);
        $token = $connection->real_escape_string($_GET["token"]);

        $data = $connection->query("SELECT id FROM users WHERE email='$email' AND token='$token' AND token <> '' ");

        if (isset($_POST["register"]))
            if ($data->num_rows > 0)
            {
                $str = $connection->real_escape_string($_POST["lalala"]); 
                $password = sha1($str);
                $connection->query("UPDATE users SET password = '$password', token = '' WHERE email='$email'");
                echo "<div class='alert success'>
         New password is: $str
        </div>";}

        if ($data->num_rows > 0)
        {
            echo "<div class='alert'>
                      <span class='closebtn'>&times;</span>  
                      Invalid link!
                      </div>";
        }
    } else {
        header("Location: login.php");
        exit();
    }
    ?>

    <input type="submit"   class="login100-form-btn"   name="register" value="Inregistrare" required />    
    <br><br>

</form>

if the token is not ok I get the error, but if i have the good token and i press the register button it will redirect me to the login.php page and in the database, the password will be unchanged and the token will be the same ( not NULL as it should).

and I have no errors.

  • 1
    Please learn to use prepared statements instead of escaping. – Barmar Jun 17 '18 at 16:06
  • @Barmar and waht should i change ? –  Jun 17 '18 at 16:09
  • 1
    See https://stackoverflow.com/questions/60174/how-can-i-prevent-sql-injection-in-php Note that this is unrelated to your problem. – Barmar Jun 17 '18 at 16:11
  • How can both `$_GET["token"]` and `$_POST["register"]` be set? When the form is submitted, there's no parameters in the `action` URL. – Barmar Jun 17 '18 at 16:12
  • @Barmar and how should i fix it ? i am a beginner in php –  Jun 17 '18 at 16:13
  • @Barmar he probably gets these values from the page before but yea it will be deleted when the form gets submitted. – Niels Jun 17 '18 at 16:25
  • @Niels what should i do to avoid that ? –  Jun 17 '18 at 16:26
  • @ValentinGrigorean try `$str = $_GET['token']; $email = $_GET['email']; action="test.php?token=$str&email=$email"` – Niels Jun 17 '18 at 16:30
  • Try to learn https://www.dreamincode.net/forums/topic/370692-reset-password-system/ or https://stackoverflow.com/questions/20331689/forgot-password-script-php-mysqli-database – Sinto Jun 17 '18 at 16:32
  • @Niels and where do i put $str = $_GET['token']; $email = $_GET['email']; –  Jun 17 '18 at 16:35
  • @ValentinGrigorean as long as it's above the form tag. – Niels Jun 17 '18 at 16:38

1 Answers1

0

You need to process the reset link and the update password form separately. When the reset link is received, you display the update form. When the update form is received, you update the password.

I've also shown how to use prepared statements instead of substituting variables, to protect against SQL injection.

<?php

ini_set("display_errors", "1");
error_reporting(E_ALL);

if (isset($_GET["token"]) && isset($_GET["email"])) {
    // Process reset link
    $token = $_GET["token"];
    $email = $_GET["email"];
    $connection = new mysqli(...);

    $statement = $connection->prepare("SELECT id FROM users WHERE email= ? AND token= ? AND token <> '' ");
    $statement->bind_param("ss", $email, $token);
    $statement->execute();
    if ($statement->fetch()) {
        ?>
        Enter the new password for <?php echo $email; ?>:
        <form action="test.php" method="post" class="login100-form validate-form"> 
        <input type="hidden" name="email" value="<?php echo $email; ?>">
        <input type="hidden" name="token" value="<?php echo $token; ?>">
        <div class="wrap-input100 validate-input m-b-50" data-validate="Enter password">
        <input type="password" class="input100"   name="lalala"  required/> 
        <span class="focus-input100" data-placeholder="Parola"></span>
        </div>
        <input type="submit" class="login100-form-btn" name="register" value="Inregistrare" /> 
        </form>
    } else {
        echo "<div class='alert'>
                  <span class='closebtn'>&times;</span>  
                  Invalid link!
              </div>";
    }
    exit();
}

if (isset($_POST["register"])) {
    // Process password form
    $token = $_POST["token"];
    $email = $_POST["email"];
    $password = password_hash($_POST["lalala"]);

    // Verify that the token is still correct
    $statement = $connection->prepare("SELECT id FROM users WHERE email= ? AND token= ? AND token <> '' ");
    $statement->bind_param("ss", $email, $token);
    $statement->execute();
    if ($statement->fetch()) {
        $statement = $connection->prepare("UPDATE users SET password = ?, token = '' WHERE email=? AND token = ?");
        $statement->bind_param("sss", $password, $email, $token);
        $statement->execute();
        echo "<div class='alert success'>
              New password is: $str
              </div>";
    } else {
        echo "<div class='alert'>
                  <span class='closebtn'>&times;</span>  
                  Invalid token!
              </div>";
    }
    exit();
}
header("Location: login.php");
exit();
?>
Barmar
  • 741,623
  • 53
  • 500
  • 612
  • I can't run my code since I don't have your database, so it's possible I made some typos. What are the errors? – Barmar Jun 18 '18 at 19:19