Mysql
 sql >> Datenbank >  >> RDS >> Mysql

Wie kann ich meine Codeiginter-Passwort-Reset-Funktion sicher machen?

Ich habe Ihren Code gelesen und denke, selbst wenn ich ein Zeitlimit für die Verwendung eines neuen Tokens hinzufüge, ist es immer noch nicht sicher. Laut owasp-Cheats zur Passwortwiederherstellung , du kannst es besser machen. Ich kürze es ein wenig für dich. Sie nennen fünf Punkte.

  1. Verwenden Sie einige Daten, die Sie bei der Benutzerregistrierung gesammelt haben – das kann Geburtstag, Handynummer, Nachname usw. sein.
  2. Verwenden Sie Sicherheitsfragen und geben Sie die Antworteingaben als reinen Text ein, machen Sie kein Dropdown oder ähnliches. Begrenzen Sie hier die Anzahl der Vermutungen. Seien Sie nicht trivial und erfinderisch bei der Konstruktion dieser Fragen.
  3. Nach Schritt zwei wird empfohlen, das Benutzerkonto sofort zu sperren. Generieren Sie ein zeitlich begrenztes Passwort-Token und senden Sie es (versuchen Sie es zumindest) über einen anderen Kommunikationskanal, vielleicht per SMS oder an eine sekundäre E-Mail.
  4. Behalten Sie die Sitzung im Auge und erlauben Sie das Zurücksetzen des Passworts nur während der aktuellen Sitzung. Erzwingen Sie in diesem Schritt die Passwortkomplexität (dafür können Sie ein jquery-Plug-in verwenden).
  5. Versuchen Sie, Benutzeraktionen, IP-Adressen und Browserdaten zu protokollieren. Konzentrieren Sie sich auf fehlgeschlagene Versuche oder die Verwendung abgelaufener Token. Auf diese Weise können Sie schädliches Verhalten überwachen und einige Schlussfolgerungen ziehen.

Und hier ist mein kleines Upgrade. Ich verwende die Spalte updated_at, die in vielen anderen Situationen nützlich sein kann, oder Sie können Ihre eigene Spalte angeben, um nur die Zeit zum Zurücksetzen des Passworts zu begrenzen.

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