CodeIgniter3 Ajax删除功能前端ID被篡改导致数据误删如何解决?
CodeIgniter3 表格删除功能安全加固方案
核心防护措施
1. 后端增加权限校验(必须做的核心防护)
- 接收到删除请求后绝对不能直接用传入的ID执行删除操作,必须先校验当前登录用户是否具备该数据的操作权限:
public function delete() { // 先校验登录状态 if (!$this->session->userdata('is_login')) { $this->output->set_status_header(403); exit; } $current_user_id = $this->session->userdata('user_id'); $request_id = $this->input->post('id'); // 先查询待删除数据的归属信息 $data_info = $this->db->get_where('你的业务表名', ['id' => $request_id])->row_array(); // 数据不存在、或者归属用户不是当前登录用户,直接拒绝请求 if (empty($data_info) || $data_info['user_id'] != $current_user_id) { $this->output->set_status_header(403); echo json_encode(['code' => 0, 'msg' => '无操作权限']); exit; } // 校验通过才执行删除操作 $this->db->delete('你的业务表名', ['id' => $request_id]); echo json_encode(['code' => 1, 'msg' => '删除成功']); }
2. 替换明文自增ID为混淆加密ID
- 不要直接把数据库的自增ID暴露到前端,渲染页面时对原始ID做加密处理,后端接收参数后再解密使用,避免用户轻易猜测到合法ID:
// 后端输出页面时用CI3自带加密类加密ID $this->load->library('encryption'); $encrypt_id = $this->encryption->encrypt($raw_id); // 前端用data属性存储加密ID,不要用原生id属性存业务ID,避免id重复冲突 <button type="button" data-id="<?php echo $encrypt_id; ?>"></button> // 后端接收参数后先解密再使用 $del_id = $this->encryption->decrypt($this->input->post('id'));
3. 新增操作签名校验
- 后端渲染页面时为每个删除按钮生成专属签名,前端提交请求时携带签名,后端比对一致才允许操作,避免用户篡改ID:
// 后端生成签名,密钥存在配置文件中不要暴露到前端 $secret_key = $this->config->item('delete_sign_secret'); $sign = md5($raw_id . $current_user_id . $secret_key); // 按钮存储签名 <button type="button" data-id="<?php echo $encrypt_id; ?>" data-sign="<?php echo $sign; ?>"></button> // 前端AJAX请求携带sign参数 data:{[csrfName]:csrfHash, id:id, sign: sign}, // 后端解密ID后校验签名 if (md5($del_id . $current_user_id . $secret_key) != $this->input->post('sign')) { $this->output->set_status_header(403); exit; }
4. 替换物理删除为软删除
- 不直接执行物理删除操作,给业务表新增
deleted_atdatetime类型字段,删除时仅更新该字段,即使出现误操作也可以恢复数据:
// 替换delete操作为update标记删除 $this->db->update('你的业务表名', ['deleted_at' => date('Y-m-d H:i:s')], ['id' => $del_id]); // 正常业务查询时过滤已删除数据 $this->db->where('deleted_at IS NULL');
5. 增加操作频率限制
- 对同一用户的删除操作做频率限制,避免被批量爆破ID:
// 统计1分钟内的删除次数 $delete_count = $this->session->userdata('delete_count') ?: 0; $delete_time = $this->session->userdata('delete_time') ?: time(); if (time() - $delete_time < 60) { if ($delete_count >= 5) { // 1分钟最多允许删除5次 $this->output->set_status_header(429); exit; } $this->session->set_userdata('delete_count', $delete_count + 1); } else { $this->session->set_userdata('delete_count', 1); $this->session->set_userdata('delete_time', time()); }
内容的提问来源于stack exchange,提问作者Mecit Akşahin
相关产品推荐
相关产品推荐

