sql >> Databasteknik >  >> RDS >> Mysql

Hur gör jag min kodiginter lösenordsåterställningsfunktion säker?

Jag har läst din kod och jag tror att även om jag lägger till tidsgräns för att använda ny token så är den fortfarande inte säker. Enligt owasp cheatsheat om lösenordsåterställning , du kan bättre än så. Jag förkortar det lite för dig. De nämner fem punkter.

  1. Använd vissa data som du samlat in i användarregistreringsprocessen – det kan vara födelsedag, mobiltelefonnummer, efternamn etc.
  2. Använd säkerhetsfrågor och skriv in svarsinmatningarna som ren text, gör inte rullgardinsmenyn eller något liknande. Begränsa antalet gissningar här. Var icke-trivial och uppfinningsrik när du konstruerar dessa frågor.
  3. Efter steg två rekommenderas det att låsa användarkontot omedelbart. Generera ett tidsbegränsat lösenordstoken och skicka det (försök åtminstone) via en annan kommunikationskanal, kanske med sms eller till sekundär e-post.
  4. Håll ett öga på sessionen och låt endast återställa lösenordet under pågående session. Framtvinga lösenordskomplexitet i det här steget (du kan använda någon jquery-plugin för det).
  5. Försök att logga användaråtgärder, IP-adress, webbläsardata. Fokusera på misslyckade försök eller att använda utgångna tokens. På så sätt kan du övervaka skadliga beteenden och dra några slutsatser.

Och här är min lilla uppgradering. Jag använder kolumnen updated_at, som kan vara användbar i många andra situationer eller så kan du ange din egen kolumn endast för att begränsa tiden för återställning av lösenord.

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



  1. Finns det en otillåten teckenlista för mysql-tabellens kolumnnamn?

  2. Varför använda en LÄS UNENGÅNGAD isoleringsnivå?

  3. Fel:ORA-00955:namn används redan av ett befintligt objekt i Oracle Function

  4. Mysql-funktion för att transformera icke-nullvärden