Mysql
 sql >> Base de données >  >> RDS >> Mysql

Comment sécuriser la fonction de réinitialisation de mon mot de passe codeiginter ?

J'ai lu votre code et je pense que même si j'ajoute un délai pour l'utilisation d'un nouveau jeton, il n'est toujours pas sécurisé. Selon owasp cheatsheat sur la récupération de mot de passe , Tu peux faire mieux que ça. Je vous la raccourcis un peu. Ils nomment cinq points.

  1. Utilisez certaines données que vous avez collectées lors du processus d'inscription de l'utilisateur :il peut s'agir de l'anniversaire, du numéro de téléphone portable, du nom de famille, etc.
  2. Utilisez des questions de sécurité et mettez les entrées de réponse sous forme de texte pur, ne faites pas de liste déroulante ou quelque chose comme ça. Limitez ici le nombre de suppositions. Soyez non trivial et inventif dans la construction de ces questions.
  3. Après la deuxième étape, il est recommandé de verrouiller immédiatement le compte utilisateur. Générez un jeton de mot de passe limité dans le temps et envoyez-le (essayez au moins) via différents canaux de communication, peut-être par SMS ou par e-mail secondaire.
  4. Gardez un œil sur la session et autorisez la réinitialisation du mot de passe uniquement pendant la session en cours. Appliquez la complexité du mot de passe à cette étape (vous pouvez utiliser un plugin jquery pour cela).
  5. Essayez de consigner les actions de l'utilisateur, l'adresse IP, les données du navigateur. Concentrez-vous sur les tentatives infructueuses ou sur l'utilisation de jetons expirés. De cette façon, vous pouvez surveiller les comportements malveillants et tirer des conclusions.

Et voici ma petite mise à jour. J'utilise la colonne updated_at, qui peut être utile dans de nombreuses autres situations ou vous pouvez spécifier votre propre colonne uniquement pour limiter le temps de réinitialisation du mot de passe.

<?php

public function recover(){
    $data['main_content'] = 'auth/recover';
    $this->load->view('public/layouts/home_main', $data);
}

public function recover_account(){
    $this->form_validation->set_rules('username','Username','trim|xss_clean|required');
    if ($this->form_validation->run() == FALSE){
        //Show View
        $data = array(
            'errors' => validation_errors()
        );
        $this->session->set_flashdata($data);
        $data['main_content'] = 'auth/recover';
        $this->load->view('public/layouts/home_main', $data);
    }
    else{
        $account = $this->input->post('username');
        if($this->User_model->user_exist($account)){
            $options = [
                'cost' => 8,
                'salt' => mcrypt_create_iv(22, MCRYPT_DEV_URANDOM),
            ];
            $temp_pass = password_hash(rand(23456,975655), PASSWORD_BCRYPT, $options);
            $reset_code = rand(23456,975655);
            $data = array(
                'reset_link_code' => $reset_code
            );
            $this->session->set_userdata($data);

            $this->email->from('[email protected]', 'Your Name');
            $this->email->to('[email protected]');
            $this->email->subject($reset_code);
            $this->email->message(
                'Testing the email class.'.' pass: <a href="'.base_url().'auth/reset_password?user='.urlencode($account).'&code='.urlencode($temp_pass).'&rstc='.urlencode($reset_code).'">Click Here</a>'
            );
            $db_pass = array(
                'password' => $temp_pass,
                'updated_at' => time() //or even date("Y-m-d H:i:s")
            );
            $this->db->where('email', $account);
            $this->db->or_where('username', $account);
            $this->db->update('users', $db_pass);

            if($this->email->send()){
                echo 'Passowrd resend link sent to email';
            }else{
                echo 'email count not check, pls talk to support';
            }
        }else{
            echo "User not Fount";
        }
    }
}
function reset_password(){
    $email = urldecode($this->input->get('user', true));
    $temp_pass = urldecode($this->input->get('code', true));
    $reset_code = urldecode($this->input->get('rstc', true));

    if($email && $temp_pass && $reset_code){

        $this->form_validation->set_rules('user','Username','trim|xss_clean|min_length[4]');
        $this->form_validation->set_rules('newpass','Password','trim|xss_clean|required|min_length[4]|max_length[50]');
        $this->form_validation->set_rules('newpass2','Confirm Password','trim|xss_clean|required|matches[newpass]');

        if($reset_code == $this->session->userdata('reset_link_code')){
            //get user data by email
            //$user = $this->User_model->get_heshed_password($email);
            $user = $this->User_model->get_heshed_password_and_updated_value($email);

            //calculate time difference
            $dbdate = strtotime($user->updated_at);
            if (time() - $dbdate > 15 * 60) {
                // 15 mins has passed
                $time_allowed = false;
            } else {
                $time_allowed = true;
            }

            if($temp_pass == $user->password && $time_allowed){
                if ($this->form_validation->run() == FALSE){
                    //Show View
                    $data = array(
                        'errors' => validation_errors()
                    );
                    $this->session->set_flashdata($data);
                    $data['main_content'] = 'auth/reset_password';
                    $this->load->view('public/layouts/home_main', $data);
                }
                else{
                    $options = [
                        'cost' => 8,
                        'salt' => mcrypt_create_iv(22, MCRYPT_DEV_URANDOM),
                    ];
                    $password = $this->input->post('newpass');
                    $passtodb = password_hash($password, PASSWORD_BCRYPT, $options);
                    $data = array(
                        'password' => $passtodb
                    );
                    $this->db->where('email', $email);
                    $this->db->or_where('username', $email);
                    $this->db->update('users', $data);
                    redirect('account');
                }

            }
        }else{
            echo 'invalid reset code';
        }

    }else{
        redirect('/');
    }
}