This question already has answers here:
Does CodeIgniter automatically prevent SQL injection?
(12 answers)
Closed 9 years ago.
I want to prevent my statement for injection but i am getting confused about active records and query bindings.
This is my current mysql query called results.
$results = $this->EE->db->query("SELECT t.transactionid, t.transactiontime, t.created, ct.title, cd.field_id_6, cd.field_id_5, cd.field_id_7, t.pricebefordiscount, t.priceafterdiscount, t.error, t.cardid, em.email, emd.m_field_id_2, emd.m_field_id_6, emd.m_field_id_5, emd.m_field_id_7, emd.m_field_id_4, t.restaurant_id
FROM exp_members as em
INNER JOIN transactions as t on (em.member_id = t.cardid-10000000)
INNER JOIN exp_channel_titles as ct on (t.restaurant_id = ct.entry_id)
INNER JOIN exp_channel_data as cd on (ct.entry_id = cd.entry_id)
INNER join exp_member_data as emd on em.member_id = emd.member_id
WHERE em.member_id = '".($_GET['cardid']-10000000)."'");
And this is how i tried to prevent mysql injection. Is this safe enough?
$results = $this->EE->db->query("SELECT t.transactionid, t.transactiontime, t.created, ct.title, cd.field_id_6, cd.field_id_5, cd.field_id_7, t.pricebefordiscount, t.priceafterdiscount, t.error, t.cardid, em.email, emd.m_field_id_2, emd.m_field_id_6, emd.m_field_id_5, emd.m_field_id_7, emd.m_field_id_4, t.restaurant_id
FROM exp_members as em
INNER JOIN transactions as t on (em.member_id = t.cardid-10000000)
INNER JOIN exp_channel_titles as ct on (t.restaurant_id = ct.entry_id)
INNER JOIN exp_channel_data as cd on (ct.entry_id = cd.entry_id)
INNER join exp_member_data as emd on em.member_id = emd.member_id
WHERE em.member_id = '".$this->db->escape(($_GET['cardid']-10000000))."'");
But is this also an option or ?
$this->load->database();
$this->load->library('table');
$this->db->select(' t.transactionid, t.transactiontime, t.created, ct.title, cd.field_id_6, cd.field_id_5, cd.field_id_7, t.pricebefordiscount, t.priceafterdiscount, t.error, t.cardid, em.email, emd.m_field_id_2, emd.m_field_id_6, emd.m_field_id_5, emd.m_field_id_7, emd.m_field_id_4, t.restaurant_id');
$this->db->from('exp_members');
$this->db->join('transactions', 'exp_members.member_id = transactions.cardid-10000000', 'inner');
$this->db->join('exp_channel_titles', 'transactions.restaurant_id = exp_channel_titles.entry_id', 'inner');
$this->db->join('exp_channel_data', 'exp_channel_titles.entry_id = exp_channel_data.entry_id', 'inner');
$this->db->join('exp_member_data', 'exp_members.member_id = exp_member_data.member_id', 'inner');
$this->db->where('exp_members.member_id', $this->db->escape(($_GET['cardid']-10000000)));
$query = $this->db->get();
echo $query;
Is this safe enough or right approach or am i missing something.
Last two approaches are correct to avoid SQL injection. On last code, using Active Record, you don't need to call escape as CodeIgniter will do it automatically.
Related
This question already has answers here:
Nested joins in Codeigniter
(2 answers)
Closed 1 year ago.
I am new to Codeigniter, and I want to convert the SQL query into the Codeigniter-style query
My query looks like this :
SELECT tbl_detail_order.ID, tbl_detail_order.order_id, tbl_detail_order.produk, products.name, tbl_detail_order.qty, tbl_detail_order.harga, tbl_order.tanggal, tbl_pelanggan.nama, tbl_pelanggan.alamat, tbl_pelanggan.telp
FROM tbl_pelanggan
INNER JOIN (tbl_order INNER JOIN
(products INNER JOIN tbl_detail_order
ON products.kd_barang = tbl_detail_order.produk)
ON tbl_order.ID = tbl_detail_order.order_id)
ON tbl_pelanggan.ID = tbl_order.pelanggan;
And I try to make it in Codeigniter like this
public function getAllJoin()
{
$this->db->select('tbl_detail_order.ID, tbl_detail_order.order_id, tbl_detail_order.produk, products.name, tbl_detail_order.qty, tbl_detail_order.harga, tbl_order.tanggal, tbl_pelanggan.nama, tbl_pelanggan.alamat, tbl_pelanggan.telp');
$this->db->from('tbl_detail_order');
$this->db->join('tbl_order','tbl_detail_order.order_id = tbl_order.id','INNER');
$this->db->join('tbl_pelanggan','tbl_order.pelanggan = tbl_pelanggan.id','INNER');
$this->db->join('products','products.kd_barang = tbl_pelanggan.id','INNER');
$query = $this->db->get();
return $query->result_array();
}
Can you correct my code? Is it wrong or right?
As this other post mentions, there isn't an API for nested joins in the CodeIgniter DB syntax. So you just use the outer one, and move the rest inline with that.
public function getAllJoin()
{
$this->db->select('tbl_detail_order.ID, tbl_detail_order.order_id, tbl_detail_order.produk, products.name, tbl_detail_order.qty, tbl_detail_order.harga, tbl_order.tanggal, tbl_pelanggan.nama, tbl_pelanggan.alamat, tbl_pelanggan.telp');
$this->db->from('tbl_detail_order');
$this->db->join('tbl_order INNER JOIN (products INNER JOIN tbl_detail_order ON products.kd_barang = tbl_detail_order.produk) ON tbl_order.ID = tbl_detail_order.order_id','tbl_detail_order.order_id = tbl_order.id','INNER');
$query = $this->db->get();
return $query->result_array();
}
I have a problem with active record codeigniter ver 2 wih special criteria like this:
$this->db->select('t_po_detail_item, t_process_shif, m_machine_lines, m_machine_mac, t_po_detail_no,
t_prod_lot, CONCAT(t_prod_lot, "-", t_prod_sublot) AS nolot,
COUNT(t_prod_sublot) AS qtybox, SUM(t_process_qty) AS qtypcs,
ROUND((SUM(t_process_qty)*m_process_weight)/1000,1) AS qtyberat', FALSE);
$this->db->join(self::$table2, 't_process_prod_id = t_prod_id', 'left')
->join(self::$table3, 't_prod_lot = t_po_detail_lot_no', 'left')
->join(self::$table5, 't_process_machine = m_machine_id', 'left')
->join(self::$table4, 'CONCAT_WS("-",t_po_detail_item, t_process_cat) = CONCAT_WS("-",m_process_id, m_process_proc_cat_id)', 'left');
$this->db->where('t_process_cat', 16);
$this->db->group_by('nolot');
$query = $this->db->get(self::$table1);
there are have special criteria join condition with concat WS. If i use standard query mysql, the query is running ok.
$sql = 'SELECT t_po_detail_item, t_process_shif, m_machine_lines, m_machine_mac, t_po_detail_no, t_prod_lot, CONCAT_WS("-",t_prod_lot, t_prod_sublot) AS nolot,
COUNT(t_prod_sublot) AS qtybox, SUM(t_process_qty) AS qtypcs, ROUND((SUM(t_process_qty)*m_process_weight)/1000,1) AS qtyberat
FROM `t_process`
LEFT JOIN t_prod ON t_process_prod_id = t_prod_id
LEFT JOIN t_po_detail ON t_prod_lot = t_po_detail_lot_no
LEFT JOIN m_machine ON t_process_machine = m_machine_id
LEFT JOIN m_process ON CONCAT_WS("-",t_po_detail_item, t_process_cat) = CONCAT_WS("-",m_process_id, m_process_proc_cat_id)
WHERE t_process_cat=16
GROUP BY(nolot)';
$query = $this->db->query($sql);
There are wrong in my active record code ?
regards,
Neos.
When using MySQL functions inside Codeigniter query builder, you need functions to be outside quotes "", so you need to pass an optional fourth parameter to join, which says rather to escape the inputs or not, and your query becomes,
$this->db->join($table, $condition, $join_type, false);
Read more here: CI Docs - Query Builder
I am new to PHP PDO and converting some regular MySQL queries to work with PDO.
The query below when tested in phpMyAdmin works great when the assigned values replaced the current placeholders in the SQL statement. But when I configure it to work as it is now with PDO, it does not produce any results or errors. Can someone please tell me or show me what is it that I am doing wrong?
Someone told me that I cannot pass parameters as references in the array.
And if correct, what is the best way for creating a solution and by using only the user ID passed through to the variable $uid. Thanks.
<p>// For testing</p>
<pre>$uid = 1;</pre>
<p> </p>
<pre>$array = array(
':uId' => ''.$uid.'',
':aId' => 'u.user_id',
':gID' => 'a.group_id',
':eID' => 'a.entry_id',
':pID' => 'a.permit_id'
);</pre>
// create the sql for qd_user_usam table
$sql = "SELECT u.user_id, a.acl_id, g.group_name, e.entry_level, p.permit_level
FROM qd_users as u, qd_users_acl as a, qd_users_group as g, qd_users_entry as e, qd_users_permission as p
WHERE u.user_id = :uID
AND a.acl_id = :aID
AND g.group_id = :gID
AND e.entry_id = :eID
AND p.permit_id = :pID";
<p>try
{</p>
<p>// Build the database PDOStatement</p>
<pre>$_stmt = $this->_dbConn->prepare($sql);</pre>
<pre>$_stmt->execute($array);</pre>
<pre>}
catch(PDOException $e)
{</pre>
<pre>$this->_errorMessage .= 'Error processing user login access. <br /> Line #'.__LINE__ .' '.$e ;</pre>
<pre>die($this->_errorMessage);
}</pre>
<pre>$results = $_stmt->fetchAll(PDO::FETCH_ASSOC);</pre>
<pre>return $results;</pre>
<pre>$results = null;</pre>
<pre>$this->_dbConn = null;</pre>
You take prepared statements wrong.
Thy have to be used not to represent whatever value in the query, but dynamically added data only.
While a.group_id is a column name and have to be written as is, without prepared statements.
// For testing
$uid = 1;
// create the sql for qd_user_usam table
$sql = "SELECT u.user_id, a.acl_id, g.group_name, e.entry_level, p.permit_level
FROM qd_users as u, qd_users_acl as a, qd_users_group as
g, qd_users_entry as e, qd_users_permission as p
WHERE u.user_id = ?
AND a.acl_id = u.user_id
AND g.group_id = a.group_id
AND e.entry_id = a.entry_id
AND p.permit_id = a.permit_id";
$_stmt = $this->_dbConn->prepare($sql);
$_stmt->execute(array($uid));
The problem is that you're trying to write your JOINs implicitly by binding the joined columns as parameters, which would not work. The parameters can not reference another column; they are seen as strings in this case. If you rewrite the query like this it should fix the JOIN problem:
SELECT u.user_id, a.acl_id, g.group_name, e.entry_level, p.permit_level
FROM qd_users AS u
JOIN qd_users_acl AS a ON (u.user_id = a.acl_id)
JOIN qd_users_group AS g ON (g.group_id = a.group_id)
JOIN qd_users_entry AS e ON (e.entry_id = a.entry_id)
JOIN qd_users_permission AS p ON (p.permit_id = a.permit_id)
WHERE u.user_id = :uID
I am trying to build a social network using Zend Framework. However, recently I have difficulty in making some complex SQL queries into Zend language. For example:
"SELECT t.plural_name, p.name as users_name, u.ID
FROM users u, profile p, relationships r, relationship_types t
WHERE t.ID=r.type
AND r.accepted=1
AND (r.usera={$user} OR r.userb={$user})
AND IF( r.usera={$user},u.ID=r.userb,u.ID=r.usera)
AND p.user_id=u.ID"
How could I execute this query using Zend's select() object? Thank you very much!
Whenever I have complex queries to deal with, I usually try to run them in MySQL. Once I have found the exact SQL statement, I start to 'translate' it to Zend. I seems a bit complex but in the long run, you get to do them in Zend right away. Here is how I break it down.
First figure out what the SQL statement is:
SELECT t.plural_name, p.name as users_name, u.ID
FROM users u, profile p, relationships r, relationship_types t
WHERE t.ID=r.type AND r.accepted=1 AND
(r.usera={$user} OR r.userb={$user}) AND
IF( r.usera={$user},u.ID=r.userb,u.ID=r.usera) AND
p.user_id=u.ID
Now, you will want to convert all the relationships to joins. The joins are somewhat scary at the beginning but it's simply a way to put the table and the criteria on which it joins to another table in one line.
SELECT t.plural_name, p.name AS users_name, u.ID
FROM users u
INNER JOIN profile AS p ON p.user_id = u.ID
INNER JOIN relationships AS r ON IF(r.usera={$user}, u.ID=r.userb, u.ID=r.usera)
INNER JOIN relationship_types AS t ON t.ID = r.type
WHERE
(r.usera={$user} OR r.userb={$user}) AND
r.accepted=1
Now that it is written in a more 'Zend friendly' way, you can easily start to convert it to Zend:
$select = $this->select()->setIntegrityCheck(false);
$select->from(array('u'=>'users'), '');
$select->join(array('p'=>'profile'), 'p.user_id = u.ID', '');
$select->join(array('r'=>'relationships'), 'IF(r.usera={$user}, u.ID=r.userb, u.ID=r.usera)', '');
$select->join(array('t'=>'relationship_types'), 't.ID = r.type', '');
$select->columns(array(
't.plural_name',
'users_name'=>'p.name',
'u.ID'));
$select->where('r.usera={$user}');
$select->orWhere('r.userb={$user}');
$select->where('r.accepted=1');
And that should do the job.
You can take this as example:(though its not complete)
<?php
$this->_query = $this->_DB->select()->from(array('u'=>'users'),array('(u.ID)'))
->join(array('p'=>'profile'),
'p.user_id = u.ID',
'p.name AS users_name')
->join(array('r'=>'relationships'),
'r.userb = u.ID')
->join(array('t'=>'relationship_types'),
't.ID = r.type',
't.plural_name')
->where('t.ID = r.type AND r.accepted = 1')
->where('r.usera = :user')
->orWhere('r.userb = :user')
->bind(array('user'=>$user));
For really complex queries it might be easier just to use SQL. It is only important that all parameters going into the query are properly escaped to prevent SQL injections.
I want to generate xml file from several tables in a MySQL database using PHP.
$query = "
SELECT
t.value,
d.value,
ty.value,
p.id,
p.ref,
p.is_renting,
p.price,
p.adress,
p.living_space,
p.rooms
FROM
jos_jea_properties p
INNER JOIN
jos_jea_towns t
ON
t.id = d.town_id
INNER JOIN
jos_jea_departments d
ON
d.id = p.department_id
INNER JOIN
jos_jea_types ty
ON
ty.id = p.type_id";
$result = mysql_query ($query, $link) or die("Could not complete database query");
But, it show me Could not complete database query, have you any idea?
There's something wrong in your query. Use mysql_error() to get the message returned by MySQL.
$result = mysql_query ($query, $link) or die("Could not complete database query: ".mysql_error()));
However, your query gets a lot of fields named value. Use aliases instead, otherwise they're getting replaced
$query = "SELECT t.value t_value, d.value d_value, ty.value ty_value,
p.id, p.ref, p.is_renting, p.price, p.adress,
p.living_space, p.rooms FROM jos_jea_properties
p INNER JOIN jos_jea_towns t ON t.id = d.town_id
INNER JOIN jos_jea_departments d ON d.id = p.department_id
INNER JOIN jos_jea_types ty ON ty.id = p.type_id";
Have you an idea about a code php How to generate a file xml for image since mysql database using php?