Hi guys,
I am debating with someone on the security of the following method:
He insists it could allow someone to take control or delete the database.
$limit, $offset and $filters are passed from the controller and I've got them through $this->input->get('varname') method.
He says that I should escape the $filter variables before I pass them to the $this->db->where method.
Currently I have something like $sql .= " b.status = '" . $filters['product_status'] . "'";
He says that I should have do it like $sql .= " b.status = '" . $this->db->escape($filters['product_status']) . "'";
As far as I know where method is already escaping the strings, there is no need to do what he suggests.
Also before getting to the Model method the input -> get() method is doing xss filtering as I set up the variable in config to be true:
$config['global_xss_filtering'] = TRUE;
Plus the security filtering method is called automatically when a new controller is invoked.
So my question: Are there any security issues with building the queries this way?
PHP Code:
public function getOrdersFiltered($limit, $offset, $filters) {
$order_sort = "DESC";
if ($filters['order_sort'] == 2) {
$order_sort = "DESC";
} else if ($filters['order_sort'] == 1) {
$order_sort = "ASC";
}
$order_by = 'a.date_added';
if ($filters['order_by'] == '1') {
$order_by = 'a.date_added';
} else if ($filters['order_by'] == 2) {
$order_by = "a.email";
} else if ($filters['order_by'] == 3) {
$order_by = 'CONCAT(a.first_name," ", a.last_name)';
} else if ($filters['order_by'] == 4) {
$order_by = "a.order_id";
} else if ($filters['order_by'] == 5) {
$order_by = "b.product_name";
} else if ($filters['order_by'] == 6) {
$order_by = "b.product_status";
}
$sql = "";
if ($filters['product_status'] == "All") {
$sql .= " b.status IS NOT NULL";
} else {
$sql .= " b.status = '" . $filters['product_status'] . "'";
}
if (!empty($filters['customer_name'])) {
$sql .= " AND CONCAT(a.first_name,' ', a.last_name) LIKE '%" . $filters['customer_name'] . "%'";
}
if (!empty($filters['customer_email'])) {
$sql .= " AND a.email LIKE '" . $filters['customer_email'] . "'";
}
if (!empty($filters['order_id'])) {
$sql .= " AND a.order_id = '" . $filters['order_id'] . "'";
}
if (!empty($filters['order_date'])) {
$sql .= " AND a.date_added = '" . $filters['order_date'] . "'";
}
if (!empty($filters['product_ordered'])) {
$sql .= " AND b.product_name LIKE '%" . $filters['product_ordered'] . "%'";
}
if (!empty($filters['state_shipping_info'])) {
$sql .= " AND a.delivery_address LIKE '%\"state_county\":\"" . $filters['state_shipping_info'] . "\"%'";
}
$this -> db -> limit($limit, $offset);
$this -> db -> order_by($order_by, $order_sort);
$this -> db -> where($sql);
$this -> db -> group_by('a.order_id');
$this -> db -> join("order_products b", "b.order_id=a.order_id", "LEFT");
$this -> db -> select("*, a.status as order_status");
$orders = $this -> db -> get("orders a") -> result_array();
foreach ($orders as $key => $order) {
$this -> db -> where("order_id", $order['order_id']);
$orders[$key]['products'] = $this -> db -> get("order_products") -> result_array();
foreach ($orders[$key]['products'] as $k => $p) {
$product_options = json_decode($p['product_options'], TRUE);
$orders[$key]['products'][$k]['customized'] = FALSE;
foreach ($product_options as $po) {
if ($po['label'] == "Customization Instructions") {
$orders[$key]['products'][$k]['customized'] = TRUE;
break;
}
}
}
}
return $orders;
}