如何使用CodeIgniter安全地删除列表实体

时间:2016-11-12 11:03:18

标签: php codeigniter

我在CodeIgniter中构建待办事项列表。

我以这种方式获取当前登录用户创建的所有列表。

<?php
        $this->db->from('lists');
        $current_user =  $this->session->userdata('email');
        $st="list_by='".$current_user."'";
        $this->db->where($st, NULL, FALSE);
        $q = $this->db->get();

        foreach ($q->result() as $key => $row) {
            echo "<li>" . $row->listTitle;
        }
?>

下面我有这个删除按钮:

<a class="delete_button" onclick="return confirm('Delete list?');" href="<?php echo site_url('lists/list_delete');?>" ><i class="icon-cancel"></i></a>  

我的问题是,如果我添加id="<? $row->id;?>,如何允许用户只删除他创建的列表,我可以检查浏览器中的代码并将id更改为其他值并从其他人删除列表

确保这一点的最佳方法是什么?

3 个答案:

答案 0 :(得分:0)

您需要将会话中存储的user_id与列表中的user_id进行比较,使用CSRF保护也是一种好习惯,您可以使用user_id和session中的其他值创建一个encripted key,并发送该encripted值在每个对服务器的请求中,然后在服务器中,您需要密钥并检查该密钥中的数据是否与会话中用户的数据相对应。

或者您可以在Codeigniter中激活CSRF保护:

https://www.codeigniter.com/userguide3/libraries/security.html

答案 1 :(得分:0)

您无法阻止用户操纵客户端表单。您需要在服务器端进行验证。例如,在您的Lists控制器中。

首先,让我们将列表的ID添加到URL,因此链接将是:

<a class="delete_button" onclick="return confirm('Delete list?');" href="<?php echo site_url("lists/list_delete/{$row->id}");?>" ><i class="icon-cancel"></i></a>  

在控制器中:

class Lists extends CI_Controller {

    public function list_delete($list_id) {
        // 1. Check if the list found by $list_id belongs to the logged-in user
        // 2. If it is, delete the list
        // 3. If it's not, throw an exception, or redirect back with an error
    }
}

答案 2 :(得分:0)

检查用户是否可以删除列表的唯一可靠方法是检查服务器,如果当前用户是具有此ID的列表的所有者。

关于将列表ID传递给服务器的方法:

  • 最简单的方法是创建删除网址,例如[2016-11-12 14:39:21,114][INFO ][node ] [xxx] initializing ... [2016-11-12 14:39:22,801][INFO ][plugins ] [xxx] modules [reindex, lang-expression, lang-groovy], plugins [], sites [] [2016-11-12 14:39:22,843][INFO ][env ] [Chak] using [1] data paths, mounts [[/ (/dev/sda1)]], net usable_space [531gb], net total_space [879.9gb], spins? [no], types [ext4] [2016-11-12 14:39:22,843][INFO ][env ] [xxx] heap size [989.8mb], compressed ordinary object pointers [true] [2016-11-12 14:39:22,844][WARN ][env ] [xxx] max file descriptors [65535] for elasticsearch process likely too low, consider increasing to at least [65536] [2016-11-12 14:39:31,375][INFO ][node ] [xxx] initialized [2016-11-12 14:39:31,377][INFO ][node ] [xxx] starting ... [2016-11-12 14:39:32,616][INFO ][transport ] [xxx] publish_address {192.168.200.8:9300}, bound_addresses {192.168.200.8:9300} [2016-11-12 14:39:32,637][INFO ][discovery ] [xxx] divar_elastic/GwfnlWtzTDGv42bZA2PcMA [2016-11-12 14:39:36,042][INFO ][cluster.service ] [xxx] detected_master {xxx}{907DRgSbTv2T-dcDOwPfSw}{192.168.200.7}{192.168.200.7:9302}, added {{xxx}{TAgbh6SmShKCPEPBtUXyXw}{192.168.200.3}{192.168.200.3:9300},{xxx}{907DRgSbTv2T-dcDOwPfSw}{192.168.200.7}{192.168.200.7:9302},{xxx}{C_b3gDlpTfu1zt0RdDlckw}{192.168.200.13}{192.168.200.13:9300},{xxx}{lYOnZzFPTiuJr7JoMNfK5g}{192.168.200.4}{192.168.200.4:9300},{xxx}{BSzFHsAMRyq8cqMh22GSKg}{192.168.200.11}{192.168.200.11:9300},}, reason: zen-disco-receive(from master [{Nar}{907DRgSbTv2T-dcDOwPfSw}{192.168.200.7}{192.168.200.7:9302}]) [2016-11-12 14:39:36,143][INFO ][cluster.routing.allocation.decider] [Foo] updating [cluster.routing.allocation.disk.watermark.low] to [93%] [2016-11-12 14:39:36,143][INFO ][cluster.routing.allocation.decider] [Foo] updating [cluster.routing.allocation.disk.watermark.high] to [97%] [2016-11-12 14:39:37,661][INFO ][http ] [xxx] publish_address {192.168.200.8:9200}, bound_addresses {192.168.200.8:9200} [2016-11-12 14:39:37,664][INFO ][node ] [xxx] started ,其中ID是列表的ID(例如/lists/list_delete/ID) 关于这种方法的坏处是,如果你使用简单的/lists/list_delete/21请求 - 坏人很容易创建一个删除网址。

  • 这就是为什么我们需要更深入地使用$_GET请求仅用于此类请求。使用此方法,您可以为每个列表创建一个小表单并在服务器上处理POST请求:

    $_POST

    即使在这种情况下,您也应该尝试避免使用CSRF并使用令牌。如前所述 - 请检查此网址https://www.codeigniter.com/userguide3/libraries/security.html#cross-site-request-forgery-csrf

更进一步 - 您可以在表单中添加ajax功能,但这是另一个问题的主题)