Mysql
 sql >> Database >  >> RDS >> Mysql

Come rendere sicura la mia funzione di reimpostazione della password di codeiginter?

Ho letto il tuo codice e penso che anche se aggiungo un limite di tempo per l'utilizzo di un nuovo token, non è ancora sicuro. Secondo owasp cheatsheat sul recupero della password , Puoi fare di meglio. Te lo accorcio un po'. Nominano cinque punti.

  1. Utilizza alcuni dati che hai raccolto durante il processo di registrazione dell'utente:possono essere compleanno, numero di cellulare, cognome ecc.
  2. Usa le domande di sicurezza e inserisci le risposte come puro testo, non fare menu a discesa o cose del genere. Limita qui il numero di ipotesi. Sii non banale e fantasioso nella costruzione di queste domande.
  3. Dopo il secondo passaggio, si consiglia di bloccare immediatamente l'account utente. Genera token password a tempo limitato e invialo (almeno prova a farlo) attraverso diversi canali di comunicazione, magari con sms, o a un'e-mail secondaria.
  4. Tieni d'occhio la sessione e consenti di reimpostare la password solo durante la sessione corrente. Applica la complessità della password in questo passaggio (puoi utilizzare alcuni plugin jquery per questo).
  5. Prova a registrare le azioni dell'utente, l'indirizzo IP, i dati del browser. Concentrati sui tentativi falliti o sull'utilizzo di token scaduti. In questo modo puoi monitorare i comportamenti dannosi e trarre alcune conclusioni.

Ed ecco il mio piccolo aggiornamento. Uso la colonna update_at, che può essere utile in molte altre situazioni oppure puoi specificare la tua colonna solo per limitare il tempo di reimpostazione della password.

<?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('/');
    }
}