проверка пароля - PullRequest
       16

проверка пароля

1 голос
/ 10 декабря 2011

Мне любопытно знать: как только токен pw_reset отправляется по электронной почте, можно ли получить адрес электронной почты учетной записи реферрера для проверки или лучше проверить по IP? Я установил срок действия моего токена всего на 1 час, и даже динамические IP-адреса не меняются с такой скоростью, верно?

Некоторый код, с которым я играюсь (очень много WIP), открытый для улучшений / предложений / критики.

Заранее спасибо.

 /**
 * Reset Password Form
 * 
 * $route['auth/reset-password'] = 'reset_password_form';
 * 
 */
public function reset_password_form()
{
    $this->load->view('templates/public', array(
        'content'   =>  'auth/reset_password_form',
        'title' =>  'Password reset',
        'description'   =>  '',
        'canonical' =>  'auth'
    ));
}
/**
 * Reset Password Authentication
 * 
 * $route['auth/reset_password/validate'] = 'auth/reset_password';
 * 
 */
public function reset_password()
{
    //setup validation rules
    $config = array(
        array('field'=>'email_address', 'label' =>'Email address', 'rules'=>'trim|required|max_lenght[128]|valid_email|valid_user_email')
    );
    $this->form_validation->CI =& $this; 
    $this->form_validation->set_rules($config); 

    //run validator and confirm OR
    if($this->form_validation->run($this))
    {

        //create the token data
        $tokenhash = Auth::create_token();
        $password_token = json_encode(array(
            'token'      => $tokenhash,
            'expires'    => date('h:i:s A', strtotime($this->config->item('pw_token_expires'))), // default 1 hours
            'ip_address' =>  $this->input->ip_address()
        )); // output {"token":"3513f5ee34ED3","expires":"01:14:06 AM","ip_address":"127.0.0.1"}


        //grab a userid to use via php-activerecord custom USER model
        $user = User::get_by_email_address($this->input->post('email_address'));

        //update the user pw_token field
        try{
            if($user->update_attribute('pw_token', $password_token))
            {
                throw new \ActiveRecord\ActiveRecordException($user->errors);
            }
        }catch(\ActiveRecord\ActiveRecordException $e){
            log_message('error', $e->getMessage());
        }

        //setup email data
        //TODO : move this to USER activeRecord\Model (pre_)
        $email_data = array(
            'email_to'  =>  $user->email_address,
            'token'     =>  anchor(site_url('auth/reset_password/confirm/'.$tokenhash.'/'.$user->id.''), 'click here to reset your password'),
            'site_link' =>  anchor(site_url(), site_url())
        );

        try{
            if(Mail::send($email_data, 'reset_password.tpl.html'))
            {
                throw new Exception(Mail::errors());
            }
        }catch(Exception $e){
            log_message('error', $e->getMessage());
        }

    }
    else
    {
        $this->reset_password_form();
    }
}
/**
 * Reset Password Confirmation
 * 
 * $route['auth/reset_password/confirm/(:any)/(:num)'] = 'auth/confirm_password_reset';
 */
public function confirm_password_reset($token='', $userid='')
{
    //check for null values
    if(!$token || !$id)
    {
        redirect('/');
    }

    //ugly
    $attempts = $this->session->set_userdata('reset_pw_attempt', (int)0);
    $this->session->set_userdata('reset_pw_attempts', $attempts++);



    if(!$this->user->id != $userid && $this->session->userdata('logged_in') === (int)0)
    {
        //not great but cant validate the email, so we check to see if they have a logged in session.
        //this is not a "forgot_password request" so we should be good as long as they are logged in
        show_404();
    }
    else
    {

        //looking good so far, now lets see do they have the correct permissions
        if(in_array(PERM_UPDATE, Auth::permissions($this->user->permissions)))
        {
            if($attempts == (int)3)
            {
                $this->session->set_flashdata('', $this->lang->line('pw_reset_attempt_over'));
                redirect('/');
            }
            else
            {
                $tokn[] = json_decode($this->user->pw_token);

                if(date('h:i:s A', time()) > $tokn['expires'] && $token===$tokn['token'])
                {
                    $this->load->view('do-pw_reset_form');
                }
            }
        }
        else
        {
            $this->session->set_flashdata('info', $this->lang->line('update_permission_denied'));
            redirect('/');
        }
    }
}

Ответы [ 3 ]

1 голос
/ 10 декабря 2011

Зачем вам проверять реферала?Использование проверки с обратной связью является стандартной практикой для подтверждения адресов электронной почты пользователей.Вам не нужно проверять IP или реферер, все, что вам нужно сделать, это создать собственный хеш и отследить адрес электронной почты, а затем отправить электронное письмо с этой информацией пользователю.

Когда пользователь нажимает встроенныйЗатем вы свяжетесь с вами, чтобы подтвердить созданный вами хэш. Если хэш выстроился в линию, то пользователь подтвердил свою учетную запись электронной почты в вашей системе.

//Example Link
https://mydomain.com/verify?hash=<some_hash>

Для дополнительной безопасности вы также можете отслеживать время отправки вашей системой электронной почты.и аннулировать хеш через 24 часа.Поэтому, если пользователь щелкает по истечении 25 часов, вы сообщаете ему, что хеш-код недействителен, и спрашиваете, хотят ли они отправить еще одно электронное письмо, если это так, повторите описанную выше процедуру.

1 голос
/ 10 декабря 2011

Проверка адреса электронной почты с помощью параметра строки запроса или использование IP-ограничений - все это излишне. Если токен пароля является случайным и достаточно длинным, его невозможно будет перебором, особенно в сочетании с истечением токена И ограничением скорости догадок токена.

Ограничение IP-адреса также может быть проблемой удобства использования. Например, пользователь может запросить сброс пароля непосредственно перед уходом с работы, а затем завершить процесс сброса из дома или во время поездки домой - то есть IP-адрес пользователя изменяется между запросом сброса и подтверждением сброса.

0 голосов
/ 10 декабря 2011

Нет причин проверять реферера, если компьютер клиента скомпрометирован, и вы ничего не можете сделать, чтобы избежать угона.Что вы можете сделать, так это следить за уязвимостями CSRF.

Кроме того, после прочтения он выглядит так, как будто он проверяет 'ip_address' => $ this-> input-> ip_address ().

...