Recover password in PHP

Asked

Viewed 5,475 times

-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’s 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? Thank you!

  • 1

    There are some missing " as you can see by the Highlight of the code. Confirm if you have so in your code or if it was so only in the question

  • I don’t see where it’s missing, but I assure you my code is working. The only problem is that the user’s email is coming in the URI after the user clicks on the link that goes to it by email. This is what I need to change. But thanks for the @Isac remark

  • See this part of the code: $mensagem = "Clique <a href=".$link.">aqui</a> para recuperar sua senha. &#xA;&#xA; $mail->Body = $mensagem;. Note how the $mensagem doesn’t have the " closing

  • Yes, true, but it was at the time that I was adapting the question here for the forum. Here I am closing.. It’s just that I forgot to put

  • 2

    Not related to doubt, but extremely relevant: passwords should not be recoverable. What is usually done is to provide a link for the user to create a new password based on a token. If your password is recoverable by a user, it is vulnerable to attacks in case of data theft, a classic security breach. With few exceptions (and your situation does not seem to be one of them) passwords must be stored irreversibly. Here are some concepts about safe password storage

1 answer

5


Problem

The problem with the system you have is that anyone can recover another person’s password as long as they know that person’s email and the URI the site uses for retrievals.

If I wanted to change the password of [email protected] just sail to http://localhost/toqve/[email protected] who could do it even though he wasn’t John.

Solution

A much better and more robust solution is to generate a token that is associated with an email 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 be always unique and so it can be the primary key of the table, and the email assumed that it was a foreign key to the user table. It may also be a id if this is the key you have defined in the user table.

The token is generated dynamically the moment 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

Taken from a recovery I already did here in stackoverflow (I swapped some characters in token)

The token can be generated in many ways and should already involve notions of encryption to be secure. A simplified way to generate it in PHP would be using the function 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 has to include the generated token, and it is necessary to create a new record in the recovery table in the database. As the table has date and time, it can and should set a maximum recovery time for security reasons, forcing the person to make a new recovery if they have already passed the time limit set by you.

Once recoveries are recorded in the system, you can consult them and potentially detect abuse.

  • Very good answer!

Browser other questions tagged

You are not signed in. Login or sign up in order to post.