Php Codeigniter用户表被破坏

Php Codeigniter用户表被破坏,php,codeigniter,security,Php,Codeigniter,Security,我在我的网站上有一个重置密码表单,我不确定它是否被泄露,或者我的代码是否只是碎片。过程如下: 用户输入忘记密码的电子邮件地址 在数据库中更改密码并发送电子邮件以供使用 用户现在可以使用新密码登录并在其帐户中更改一次 (我意识到这是一个不完美的过程,但这是网站的v1版) 问题是间歇性地所有用户密码都被更改(更改为相同的密码),我一辈子都无法弄清楚。XSS和CSRF过滤器都在Codeigniter内部启用 这是我的密码: 控制器 $this->form_validation->set

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

  • 用户输入忘记密码的电子邮件地址
  • 在数据库中更改密码并发送电子邮件以供使用
  • 用户现在可以使用新密码登录并在其帐户中更改一次
(我意识到这是一个不完美的过程,但这是网站的v1版)

问题是间歇性地所有用户密码都被更改(更改为相同的密码),我一辈子都无法弄清楚。XSS和CSRF过滤器都在Codeigniter内部启用

这是我的密码:

控制器

$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));
    }
}
因此,再次重复这个问题:每隔一段时间,所有用户的密码都会被更改(更改为相同的密码)。这是怎么发生的?

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

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

    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次查询(检查电子邮件,然后更新)

公共功能重置\u密码($email,$newpass)
{
如果(!$email | |!$newpass)
返回false;
$newpass=do_hash($newpass,'md5');
$this->db->where('user\u email',$email);
$this->db->update('users',array('user_password'=>$newpass));
如果($this->db->infected_rows()<1){
return false;//未找到电子邮件
}否则{
返回true;
}
}
您还可以调用
$this->db->last_query()
查看查询以及
where()
是否有效。

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

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

    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次查询(检查电子邮件,然后更新)

公共功能重置\u密码($email,$newpass)
{
如果(!$email | |!$newpass)
返回false;
$newpass=do_hash($newpass,'md5');
$this->db->where('user\u email',$email);
$this->db->update('users',array('user_password'=>$newpass));
如果($this->db->infected_rows()<1){
return false;//未找到电子邮件
}否则{
返回true;
}
}
您还可以调用
$this->db->last_query()
查看查询以及
where()
是否有效。

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

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

    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次查询(检查电子邮件,然后更新)

公共功能重置\u密码($email,$newpass)
{
如果(!$email | |!$newpass)
返回false;
$newpass=do_hash($newpass,'md5');
$this->db->where('user\u email',$email);
$this->db->update('users',array('user_password'=>$newpass));
如果($this->db->infected_rows()<1){
return false;//未找到电子邮件
}否则{
返回true;
}
}
您还可以调用
$this->db->last_query()
查看查询以及
where()
是否有效。

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

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

    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次查询(检查电子邮件,然后更新)

公共功能重置\u密码($email,$newpass)
{
如果(!$email | |!$newpass)
返回false;
$newpass=do_hash($newpass,'md5');
$this->db->where('user\u email',$email);
$this->db->update('users',array('user_password'=>$newpass));
如果($this->db->infected_rows()<1){
return false;//未找到电子邮件
}否则{
返回true;
}
}

您还可以调用
$this->db->last_query()
查看查询,以及
where()
是否有效。

这不是对您特定问题的回答,但需要解决,而且太长,无法发表评论

不要将MD5用作密码的哈希机制。它已经过时,基本上不再提供任何安全性。相反,请使用PHP,如果没有PHP5.5,请使用。它非常容易使用,效果非常好,并且使用了更好的散列算法

其次,为用户创建新密码通常不是一个好的做法。而是创建一个在请求后1小时内过期的令牌,然后在电子邮件中传递该令牌。然后用户输入他们的电子邮件、令牌和新密码


因为我说的还不够多,所以不要使用MD5。这不是对你的具体问题的回答,但它需要解决