0

I want to take advantage of self-security of Active Records in Codeigniter.

The Requirement is:

  1. Get some serial numbers from first table based on some criteria
  2. Then check which of those serial numbers are present in second table based on some complex criteria.
  3. Finally show the results from first table which are not present in the second table resultset.

I have the following code in CI:

$this->db->select('sno');
$this->db->from('table1');
$this->db->where("cid",$cid);
$subquery=$this->db->get_compiled_select();

$this->db->select("pid")->from("table2");
$this->db->group_start();
    $this->db->group_start();
        $this->db->where("col1 <",$cin);
        $this->db->where("col2 >",$cin);
    $this->db->group_end();
    $this->db->or_group_start();
        $this->db->where("col1 <",$cout);
        $this->db->where("col2 >",$cout);
    $this->db->group_end();
    $this->db->or_group_start();
        $this->db->where("col1 >",$cin);
        $this->db->where("col1 <",$cout);
    $this->db->group_end();
    $this->db->or_group_start();
        $this->db->where("col1",$cin);
        $this->db->or_where("col2",$cout);
        $this->db->or_where("col1",$cout);
        $this->db->or_where("col2",$cin);
    $this->db->group_end();
    $this->db->or_group_start();
        $this->db->where("col2 >",$cin);
        $this->db->where("col2 <",$cout);
    $this->db->group_end();
$this->db->group_end();
$this->db->where_in("col3",$subquery);
$sbquery = $this->db->get_compiled_select();

    $this->db->from('table1');
    $this->db->where("tid",$cid);
    $this->db->where_not_in("cid",$sbquery);
    $result=$this->db->get_compiled_select();
    var_dump($result);
    exit;

This code shows the following query (as the result of var_dump):

SELECT * FROM `table1` WHERE `tid` = '6' AND `cid` NOT IN('SELECT `pid`\nFROM `table2`\nWHERE (\n (\n`col1` < \'2018-12-10\'\nAND `col2` > \'2018-12-10\'\n )\nOR (\n`col1` < \'2018-12-16\'\nAND `col2` > \'2018-12-16\'\n )\nOR (\n`col1` > \'2018-12-10\'\nAND `col1` < \'2018-12-16\'\n )\nOR (\n`col1` = \'2018-12-10\'\nOR `col2` = \'2018-12-16\'\nOR `col1` = \'2018-12-16\'\nOR `col2` = \'2018-12-10\'\n )\nOR (\n`col2` > \'2018-12-10\'\nAND `col2` < \'2018-12-16\'\n )\n )\nAND `col3` IN(\'SELECT `sno`\\nFROM `table1`\\nWHERE `cid` = \\\'6\\\'\')')

This gives wrong results when I use the following code (last 3 lines of code):

$result=$this->db->get()->result();
var_dump($result);
exit;

If I hit the same query directly in SQL, I am getting the same wrong results.

But, if I remove slashes, single quotes, new line and other special characters, to hit the rewritten query directly in sql, I get the perfectly accurate results.

SELECT * FROM `table1` WHERE `tid` = '6' AND `cid` NOT IN(SELECT `pid` FROM `table2` WHERE ((`col1` < '2018-12-10' AND `col2` > '2018-12-10') OR (`col1` < '2018-12-16' AND `col2` > '2018-12-16') OR (`col1` > '2018-12-10' AND `col1` < '2018-12-16') OR (`col1` = '2018-12-10' OR `col2` = '2018-12-16' OR `col1` = '2018-12-16' OR `col2` = '2018-12-10') OR (`col2` > '2018-12-10' AND `col2` < '2018-12-16')) AND `col3` IN(SELECT `sno` FROM `table1` WHERE `cid` = '6'))

Please suggest a solution.

0

1 Answer 1

1

Add a FALSE as third parameter on your active records subquery so the statements will not get escaped.
Change from :

$this->db->where_in("col3",$subquery);
...
$this->db->where_not_in("cid",$sbquery);

to :

$this->db->where_in("col3",$subquery,FALSE);
...
$this->db->where_not_in("cid",$sbquery,FALSE);
Sign up to request clarification or add additional context in comments.

2 Comments

Hi, but will adding FALSE impact the security concern in any manner?
From what I know it won't directly impact the security concern since it's a subquery resulted from another safe query

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.