27

I am using the Magento's functionality to insert & update queries. My requirement is that I want to take care of SQL Injection, when doing these types of queries. But I'm unable to find how Magento does this. I'm providing one start sample. Please provide me with one complete example.

<?php
$write = Mage::getSingleton("core/resource")->getConnection("core_write");
$sql = "INSERT INTO Mage_Example (Name, Email, Company, Description, Status, Date)
    VALUES ('$name', '$email', '$company', '$desc', '0', NOW())";
?>

Now I want to change the above query to prevent the possible SQL Injection. I don't want to use the default "mysql_real_escape_string()" built-in function of PHP. Can anybody please provide me with one useful solution, using the "$write" DB Handler.

Any help is greatly appreciated.

Knowledge Craving
  • 7,955
  • 13
  • 49
  • 92

4 Answers4

60

Okay, researched this one a little bit. If you can get an instance of a DB_Adapter (which I believe that resource call will return), this shouldn't be too tough. Deep down inside, Magento is based on Zend Framework, and the DB adapter specifically is descended from Zend_Db_Adapter, so you can use those methods for free. See the link before for more examples, but here's the syntax provided in the docs, which should escape your input automagically:

$write = Mage::getSingleton("core/resource")->getConnection("core_write");

// Concatenated with . for readability
$query = "insert into mage_example "
       . "(name, email, company, description, status, date) values "
       . "(:name, :email, :company, :desc, 0, NOW())";

$binds = array(
    'name'    => "name' or 1=1",
    'email'   => "email",
    'company' => "company",
    'desc'    => "desc",
);
$write->query($query, $binds);

Again, see the docs for more information.


UPDATE:

I've changed the example above. The object that you get back with your core_write request is a PDO object that exposes a query method (see above) that will let you used parameterized queries. This is BY FAR a better approach than attempting to use something like mysql_real_escape_string for data sanitization, and I've tested the above code for correctness. Note that, in contrast to most MySQL parameterized queries, the binding is done with :labels, and also that you need no quotes for your vars.

In response to your other point, and as noted below, the "right" way to do it in Magento is not to use direct queries at all. The Magento object models are well development and meant to abstract this kind of implementation detail away from you, because you shouldn't need to concern yourself with it. To do it "correctly", create a new database-based model and save the headache.

Jon Surrell
  • 9,444
  • 8
  • 48
  • 54
Joe Mastey
  • 26,809
  • 13
  • 80
  • 104
  • Thanks for the info. But I'm still at dark. Please correct me if I'm wrong. First of all, you have used "`$db`" object & used its "`insert()`" method to insert the data record into "bugs" table. Now what I really want is to use "`$write`" object (of my question) instead of this "`$db`" object. **Please treat me as a newbie in this "Zend_Db" architecture.** Again thanks for your time, but can you please try to solve it according to my question? Also please take care in providing the solution wrt Magento specifically & not "Zend_Db", although I understand the relation between the two. – Knowledge Craving Aug 26 '10 at 20:24
  • To be fair, the Magento way is not to execute the SQL directly at all. Define a data model (or an EAV model) and insert it that way. looking at the other items you mentioned, so I'll try to amend the example. – Joe Mastey Aug 26 '10 at 23:55
  • Thanks very much for such an informative & particular answer. Due to my attachments to other works, I'm currently unavailable to use your example & test my application, but definitely I will use your answer in the coming week only. So please give me a bit of time, to mark this as the suitable answer. Thanks again. – Knowledge Craving Aug 28 '10 at 06:03
13

I am using this for inserting multiple rows to the table

$table = Mage::getSingleton('core/resource')->getTableName('table_name');
$rows = array(
   array('cal_1'=>'value','cal_2'=>'value','cal_3'=>'value'),
   array('cal_1'=>'value','cal_2'=>'value','cal_3'=>'value')
);

public function insertRows($table,$rows)
{
   $write = Mage::getSingleton('core/resource')->getConnection('core_write');
   $write->insertMultiple($table,$rows);
}
user3409501
  • 141
  • 1
  • 2
2

In resource file.

public function saveToTable($param){

$table = $this->getMainTable(); 

$this->_getWriteAdapter->insert($table,array(
          'col_1'=>$param['data1']
          'col_2'=>$param['data2']
          'col_3'=>$param['data3']
      ));
}

returns number of rows affected.

Ricky Sharma
  • 1,839
  • 3
  • 24
  • 44
1

i guess escaping the $name, $email and other variables will be enought.

take a look at mysql_real_escape_string function.

0xAF
  • 205
  • 2
  • 9