Recover password in PHP

-1

I made a simple system to recover password. The system is working normally, but when the user clicks on the confirmation email, his email appears in the URI, what do I do? Here is the code:

This is the html form:

<section class="recipiente margem-topo-100">
    <form action="recuperar_por_email.php" method="post" class="coluna">
      <input type="text" name="recuperar-senha" placeholder="Insira seu email">
      <button class="icones icone-enviar"></button>
    </form>
  </section>

This is the code that sends the email and creates the variables I use:

<?php

  require_once "PHPMailer/PHPMailerAutoLoad.php";
  require_once "interno/conecta.php";
  require_once "interno/funcoes.php";


  $recupera = $_POST['recuperar-senha'];
  $link = "http://localhost/toqve/recuperar.php?recupera=".$recupera;

  $mail = new PHPMailer();

  $mail->IsSMTP();
  $mail->isHTML(true);
  $mail->CharSet = 'utf-8';
  $mail->Host = 'mx1.weblink.com.br';
  $mail->Port = 587;
  $mail->SMTPSecure = 'tls';
  $mail->SMTPAuth = true;
  $mail->Username = '[email protected]';
  $mail->Password = '*********';
  $mail->setFrom("[email protected]", "daLvz");
  $mail->FromName = 'daLvz';
  $mail->Subject = "Recuperar senha";

  $mensagem = "Clique <a href=".$link.">aqui</a> para recuperar sua senha. 

  $mail->Body = $mensagem;
  $mail->AltBody = "Conteudo do email em texto";

  $mail->addAddress($recupera);

  if($mail->Send()) {

    header("Location: confirmacao.php");
  } else {

    echo "Erro ao enviar email". $mail->ErrorInfo;
  }

This is the page that appears when the user clicks on the received email:

<?php

  require_once "cabecalho.php";
  require_once "interno/conecta.php";
  require_once "interno/funcoes.php";
  $recupera = $_GET['recupera'];
?>

<section class="recipiente margem-topo-100">

  <form class="coluna" action="sucesso.php" method="post" >
    <input type="text" name="recupera" value="<?=$recupera?>">
    <input type="password" name="senha" placeholder="insira uma nova senha">
    <button class="icones icone-enviar"></button>
  </form>
</section>

Can anyone help me? Thanks!

    
asked by anonymous 07.10.2017 / 00:35

1 answer

3

Problem

The problem with the system is that anyone can recover the password of another one as long as they know that person's email and the URI that the site uses for recoveries.

If I wanted to change the password of [email protected] , I would only have to navigate to http://localhost/toqve/[email protected] that could do it even though it was not the john.

Solution

A much better and more robust solution is to generate a token that is associated with an e-mail in a table. Something that can follow the following structure:

token                                  | email          | datahora
cf9186069dd09f16c959f70f1735c91b48549b | [email protected] | 2017-10-07 12:00:00

In this structure the token has to always be unique and so can remain as the primary key of the table, and the email assumed that it was a foreign key to the user table. It can also be a id if that is the key that is defined in the user table.

The token is generated dynamically at the time the recovery attempt is made. This token pattern is visible in the StackOverflow password reset itself:

https://stackoverflow.com/account/recover?recoveryToken=miA1WGREQDlAQDGRyUw%3d%3d%7cae52238c59a755ddd2faff86b2b2f91037048839582aa4cc88e709ASD02a4512c

Given a recovery I already did here in stackoverflow (I changed some characters in the token)

The token can be generated in many ways and should already involve cryptographic notions to be secure. A simplified way to generate it in PHP would be to use the random_bytes and bin2hex :

$token = bin2hex(random_bytes(50)); //tamanho de 50 bytes

There are other alternatives such as openssl_random_pseudo_bytes .

Additional steps

The link now needs to include the generated token, and you must create a new record in the recovery table in the database. Because the table has a date and time, it can and should set a maximum time for recovery for security reasons, forcing the person to do a new recovery if the time limit has already passed.

Once recoveries are logged on the system, it can query and potentially detect abuse.

    
07.10.2017 / 01:46