Mysql
 sql >> Baza danych >  >> RDS >> Mysql

Jak zabezpieczyć funkcję resetowania hasła codeigninter?

Przeczytałem Twój kod i myślę, że nawet jeśli dodam limit czasu na użycie nowego tokena, to nadal nie jest to bezpieczne. Według oszustwo owasp dotyczące odzyskiwania hasła , Możesz to zrobić lepiej. Skróciłem go trochę dla ciebie. Wymieniają pięć punktów.

  1. Użyj niektórych danych, które zebrałeś w procesie rejestracji użytkownika - mogą to być urodziny, numer telefonu komórkowego, nazwisko itp.
  2. Używaj pytań zabezpieczających i wstawiaj odpowiedzi jako czysty tekst, nie rób listy rozwijanej ani niczego podobnego. Ogranicz tutaj liczbę domysłów. Bądź nietrywialny i pomysłowy w konstruowaniu tych pytań.
  3. Po drugim kroku zaleca się natychmiastowe zablokowanie konta użytkownika. Wygeneruj token hasła ograniczonego czasowo i wyślij go (przynajmniej spróbuj) innym kanałem komunikacji, na przykład przez sms lub na dodatkowy e-mail.
  4. Miej oko na sesję i zezwalaj na resetowanie hasła tylko podczas bieżącej sesji. Wymuś złożoność hasła w tym kroku (możesz do tego użyć jakiejś wtyczki jquery).
  5. Spróbuj rejestrować działania użytkownika, adres IP, dane przeglądarki. Skoncentruj się na nieudanych próbach lub wykorzystaniu wygasłych tokenów. W ten sposób możesz monitorować złośliwe zachowania i wyciągać wnioski.

A oto moje małe ulepszenie. Używam kolumny updated_at, która może być przydatna w wielu innych sytuacjach lub możesz określić własną kolumnę tylko w celu ograniczenia czasu resetowania hasła.

<?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. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. wyświetlanie tygodnia według daty

  2. Kod błędu 1292 - Obcięta niepoprawna PODWÓJNA wartość - Mysql

  3. Symfony2 i Doctrine2:Nie określono identyfikatora/klucza podstawowego dla jednostki X. Każda jednostka musi mieć identyfikator/klucz podstawowy

  4. klucz mysql był za długi problem

  5. Jak dodać więcej niż jeden wiersz za pomocą Zend_Db?