Codeigniter用户表遭到入侵

时间:2014-03-20 07:57:36

标签: php codeigniter security

我的网站上有一个重置密码表单,我不确定它是否被泄露,或者我的代码是否只是fla fla。过程如下:

  • 用户输入忘记密码的电子邮件地址
  • 密码在数据库中更改,电子邮件发送使用
  • 用户现在可以使用新密码登录并在帐户中更改一次

(我意识到这是一个不完美的过程,但它是网站的v1。)

问题在于,间歇地所有用户密码都被更改(使用相同的密码),我无法解决这个问题。 Codeigniter中启用了XSS和CSRF过滤器。

这是我的代码:

控制器

$this->form_validation->set_rules('email','Email address','required');

    if ($this->form_validation->run() === FALSE)
    {
        $this->password_reset();
    }
    else 
    {
        /**
         * Generate a new password and send to model
         */

        $newpass = substr(md5(rand()),0,10);
        $this->users_model->reset_password($newpass);

        // stuff for email here
        $this->email->send();

        /**
         * Load view
         **/
        $data['content'] = 'content/login/reset_done';
        $data['title'] = 'Password Reset';
        $this->load->view($this->layout, $data);
    }
}

模型

public function reset_password($newpass)
{
    $email = $this->input->post('email');
    $query = $this->db->get_where('users', array('user_email' => $email));

    if($query->num_rows())
    {
        $newpass = do_hash($newpass, 'md5');
        $this->db->where('user_email', $email);
        $this->db->update('users', array('user_password' => $newpass));
    }
}

所以要再次重复这个问题:所有用户密码都经常被更改(使用相同的密码)。这是怎么回事?

2 个答案:

答案 0 :(得分:2)

  • 在您的模型中,请勿使用$this->input->post,而是将此数据作为参数发送。 (因为您的模型不应该像带有路径/会话/标题/等信息的控制器一样)

  • 这可能是因为$this->input->post('email')为空或''(在这种情况下,它会更新所有人,而num_rows将返回数据库中的用户总数),您必须检查for:

    public function reset_password($email, $newpass)
    {
        if(!$email || !$newpass)
            return false;
    
        $query = $this->db->get_where('users', array('user_email' => $email));
    
        if($query->num_rows())
        {
            $newpass = do_hash($newpass, 'md5');
            $this->db->where('user_email', $email);
            $this->db->update('users', array('user_password' => $newpass));
        }
    }
    

修改   - 您不需要进行2次查询(查看电子邮件然后更新)

public function reset_password($email, $newpass)
{
    if(!$email || !$newpass)
        return false;

    $newpass = do_hash($newpass, 'md5');
    $this->db->where('user_email', $email);
    $this->db->update('users', array('user_password' => $newpass));

    if ($this->db->affected_rows() < 1) {
        return false; //Email wasn't found
    } else {
        return true;
    }
}

您也可以致电$this->db->last_query();查看查询以及where()是否有效。

答案 1 :(得分:1)

这不是您具体问题的答案,但需要解决,评论时间太长。

请勿将MD5用作密码的散列机制。它已经过时了,基本上不再提供零安全性了。而是使用PHP password_hash(),如果你没有使用PHP5.5,请使用compatibility library。它非常易于使用且效果很好,并且使用了更好的散列算法。

第二,为用户创建新密码通常不是一种好习惯。而是创建一个在请求的1小时内到期的令牌,然后在电子邮件中传递它。然后用户输入他们的电子邮件,令牌和新密码。

因为我说不够,不要使用MD5