Yii Framework Forum: $_GET validation question - Yii Framework Forum

Jump to content

  • (2 Pages)
  • +
  • 1
  • 2
  • You cannot start a new topic
  • You cannot reply to this topic

$_GET validation question Rate Topic: -----

#1 User is offline   bettor 

  • Master Member
  • PipPipPipPip
  • Yii
  • Group: Members
  • Posts: 749
  • Joined: 02-February 09

Posted 08 January 2010 - 02:48 PM

Hi,

Can someone please summarize on how I should treat $_GET paramaters in terms of security. I am creating some urls by assigning $_GET parameters directly in the CHtml::link and I am also executing some queries in widgets, which use GET parameters directly in the query and I am worried about the security side of all this. If someone can summarize how I should escape all GET values please.

Regards,
b.
0

#2 User is offline   iGrog 

  • Junior Member
  • Pip
  • Yii
  • Group: Members
  • Posts: 64
  • Joined: 09-October 09

Posted 08 January 2010 - 02:59 PM

Main rule - don't believe anyone :)
Always escape user input or data user can change. In SQL queries always use parameters.

Show please example of "I am creating some urls by assigning $_GET parameters directly in the CHtml::link"
-1

#3 User is offline   megabr 

  • Standard Member
  • PipPip
  • Yii
  • Group: Members
  • Posts: 142
  • Joined: 23-March 09
  • Location:Brazil

Posted 08 January 2010 - 03:51 PM

I have also with same question... :)

I found this $this->_GET..? what is this?
trying build code for Generate complete CRUD source code with YII... any help?
post comments here:
EXTENDING CRUD GENERATION (scaffolding)

old tentative released (module generator):
http://www.yiiframew...sion/modulegen/
0

#4 User is offline   gallego123 

  • Advanced Member
  • PipPipPip
  • Yii
  • Group: Members
  • Posts: 535
  • Joined: 11-August 09
  • Location:Argentina

Posted 08 January 2010 - 04:45 PM

I'm interested!

Quote

In SQL queries always use parameters.

Why the use of parameters in the method find help?

Quote

Always escape user input or data user can change


Does that mean "escape user input"? a example?


Here is something, but only upon showing, not validate GET parameters

http://www.yiiframew...topics.security
KISS - Keep It Simple Stupid
ASAP-As Soon As Possible
http://www.yiiframew...oc/cookbook/71/
0

#5 User is offline   bettor 

  • Master Member
  • PipPipPipPip
  • Yii
  • Group: Members
  • Posts: 749
  • Joined: 02-February 09

Posted 08 January 2010 - 05:29 PM

View PostiGrog, on 08 January 2010 - 02:59 PM, said:

Main rule - don't believe anyone :)
Always escape user input or data user can change. In SQL queries always use parameters.

Show please example of "I am creating some urls by assigning $_GET parameters directly in the CHtml::link"


Hi iGrog,

thanks for assising. Here is an example:
<li><?php echo CHtml::link('Link Label',array('controller/list','id'=>$_GET['id'])); ?></li>

which creates a menu with the current id attribute.

Can you also show examples on how to escape characters and how to use parameters with sql queries in a secure way.

Thanks,
b
0

#6 User is offline   bettor 

  • Master Member
  • PipPipPipPip
  • Yii
  • Group: Members
  • Posts: 749
  • Joined: 02-February 09

Posted 09 January 2010 - 04:05 AM

I found the following comment by qiang:

http://www.yiiframew...3758

Basically in sql queries we should use bindValue or bindParam to avoid sql injection attack. This comment was posted a year ago. I would like to know if anything has changed since then. And also how to escape $_GET parameters if used directly in links or text.

Cheers,
b
0

#7 User is offline   Mike 

  • Elite Member
  • PipPipPipPipPip
  • Yii
  • Group: Members
  • Posts: 3,013
  • Joined: 06-October 08
  • Location:Upper Palatinate

Posted 09 January 2010 - 08:54 AM

View Postbettor, on 09 January 2010 - 04:05 AM, said:

Basically in sql queries we should use bindValue or bindParam to avoid sql injection attack. This comment was posted a year ago. I would like to know if anything has changed since then.


No change. Yii's DB layer was built around PDO. It takes care of correct escaping for you:
Quote from http://www.php.net/m...statements.php:

Quote

The parameters to prepared statements don't need to be quoted; the driver automatically handles this. If an application exclusively uses prepared statements, the developer can be sure that no SQL injection will occur (however, if other portions of the query are being built up with unescaped input, SQL injection is still possible).

0

#8 User is offline   Y!! 

  • Advanced Member
  • Yii
  • Group: Yii Dev Team
  • Posts: 978
  • Joined: 18-June 09

Posted 09 January 2010 - 10:20 AM

When using DAO, you need to use bindParam/bindValue in order to prevent SQL injections, as described here under "Binding Parameters". When using ActiveRecords, you don't have to care about SQL injections since Yii does all the param-binding internally.

When using $_GET parameters in html, you have to make sure the data does not contain malicious code like "<script>...". You can do it this way:

CHtml::encode($_GET['something']);


CHtml::encode() is a wrapper for the php function htmlspecialchars().

Read more about security here.
0

#9 User is offline   mbi 

  • Master Member
  • PipPipPipPip
  • Yii
  • Group: Members
  • Posts: 604
  • Joined: 08-May 09

Posted 09 January 2010 - 10:54 AM

if you expect an integer, just turn it into one via (int) or intval($_GET['id'])
0

#10 User is offline   bettor 

  • Master Member
  • PipPipPipPip
  • Yii
  • Group: Members
  • Posts: 749
  • Joined: 02-February 09

Posted 09 January 2010 - 11:22 AM

View PostY!!, on 09 January 2010 - 10:20 AM, said:

When using DAO, you need to use bindParam/bindValue in order to prevent SQL injections, as described here under "Binding Parameters". When using ActiveRecords, you don't have to care about SQL injections since Yii does all the param-binding internally.

When using $_GET parameters in html, you have to make sure the data does not contain malicious code like "<script>...". You can do it this way:

CHtml::encode($_GET['something']);


CHtml::encode() is a wrapper for the php function htmlspecialchars().

Read more about security here.


Thanks Y!!. So to summarize:

using bindParam is safe and creating links like below is safe?
<?php echo CHtml::link('Value',array('controller/action','id'=>CHtml::encode($_GET['id']))); ?>


Additionally, I would like to know when I should use the CHtmlPurifier. Is there a specific case where it should be used. I don't remember qiang using it in the blog demo?

Thanks,
b
0

#11 User is offline   Y!! 

  • Advanced Member
  • Yii
  • Group: Yii Dev Team
  • Posts: 978
  • Joined: 18-June 09

Posted 09 January 2010 - 11:48 AM

View Postbettor, on 09 January 2010 - 11:22 AM, said:

Thanks Y!!. So to summarize:

using bindParam is safe and creating links like below is safe?
<?php echo CHtml::link('Value',array('controller/action','id'=>CHtml::encode($_GET['id']))); ?>


Additionally, I would like to know when I should use the CHtmlPurifier. Is there a specific case where it should be used. I don't remember qiang using it in the blog demo?

Thanks,
b


Using parameter binding is safe, yes. You don't have to mess around with any additional function like addslashes() or mysql_real_escape_string(). Just make sure you really always bind the needed params and don't write them directly into the sql query string. As I said that only counts for DAO, not for ActiveRecord.

The way you use the CHtml::link() is safe. What you also can do is this:

<?php echo CHtml::link('Value',array('controller/action','id'=>$_GET['id'],'encode' => true)); ?>


When encode is set to true, all values of the htmloptions you define (in this case the value of "id") will be auto-encoded. Means less writing when you assign many htmloptions.

With CHtmlPurifier you can basically auto-encode a whole page or only parts of a page (like a comments list). So there's no need for CHtml::encode($comment->text); anymore. But it's slower than encode(). The nice thing however is that you may allow defined htmltags when using the Purifier. I've never used that so I can't give an example. You may look here under "options" and here for more info about the purifier.
0

#12 User is offline   megabr 

  • Standard Member
  • PipPip
  • Yii
  • Group: Members
  • Posts: 142
  • Joined: 23-March 09
  • Location:Brazil

Posted 09 January 2010 - 04:33 PM

nice... :)
trying build code for Generate complete CRUD source code with YII... any help?
post comments here:
EXTENDING CRUD GENERATION (scaffolding)

old tentative released (module generator):
http://www.yiiframew...sion/modulegen/
0

#13 User is offline   Y!! 

  • Advanced Member
  • Yii
  • Group: Yii Dev Team
  • Posts: 978
  • Joined: 18-June 09

Posted 10 January 2010 - 05:29 AM

View PostY!!, on 09 January 2010 - 11:48 AM, said:

Using parameter binding is safe, yes. You don't have to mess around with any additional function like addslashes() or mysql_real_escape_string(). Just make sure you really always bind the needed params and don't write them directly into the sql query string. As I said that only counts for DAO, not for ActiveRecord.


Just for clarification, when you pass custom sql to an ActiveRecord, you have to bind params of course.

This is unsafe:

$user = User::model()->find("`name` = '{$_GET['name']}'");


This is safe:

$user = User::model()->find("`name` = :name", array(':name' => $_GET['name']));


This is safe since Yii does auto-bind the params:

$user = new User;
$user->name = $_GET['name'];
$user->save();

0

#14 User is offline   bettor 

  • Master Member
  • PipPipPipPip
  • Yii
  • Group: Members
  • Posts: 749
  • Joined: 02-February 09

Posted 10 January 2010 - 06:37 AM

Thanks for your valuable input Y!!. How about when used with criteria

example:
$criteria->condition="value = '".$_GET['id']."'";
is this safe? Does Yii auto-bind the parameter in this case?

Thanks,
b
0

#15 User is offline   andy_s 

  • Random Member Title
  • Yii
  • Group: Moderators
  • Posts: 1,526
  • Joined: 22-June 09
  • Location:Russia, Kostroma

Posted 10 January 2010 - 06:49 AM

View Postbettor, on 10 January 2010 - 06:37 AM, said:

Thanks for your valuable input Y!!. How about when used with criteria

example:
$criteria->condition="value = '".$_GET['id']."'";
is this safe? Does Yii auto-bind the parameter in this case?

Thanks,
b


No, use the following syntax:

$criteria->condition = 'id = :id';
$user = User::model()->find($criteria, array(':id' => $_GET['id']))
// or ...
// $criteria->params = array(':id' => $_GET['id']);
// $user = User::model()->find($criteria)

1

#16 User is offline   bettor 

  • Master Member
  • PipPipPipPip
  • Yii
  • Group: Members
  • Posts: 749
  • Joined: 02-February 09

Posted 10 January 2010 - 07:48 AM

thanks andy_s.
This:
// $criteria->params = array(':id' => $_GET['id']);
// $user = User::model()->find($criteria)

works as a charm but this
$criteria->condition = 'id = :id';
$user = User::model()->find($criteria, array(':id' => $_GET['id']))

does not work. It throws a syntax error which I am unable to identify.
Error:
CDbCommand failed to execute the SQL statement: SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ':id' at line 1

0

#17 User is offline   andy_s 

  • Random Member Title
  • Yii
  • Group: Moderators
  • Posts: 1,526
  • Joined: 22-June 09
  • Location:Russia, Kostroma

Posted 10 January 2010 - 09:08 AM

View Postbettor, on 10 January 2010 - 07:48 AM, said:

thanks andy_s.
This:
// $criteria->params = array(':id' => $_GET['id']);
// $user = User::model()->find($criteria)

works as a charm but this
$criteria->condition = 'id = :id';
$user = User::model()->find($criteria, array(':id' => $_GET['id']))

does not work. It throws a syntax error which I am unable to identify.
Error:
CDbCommand failed to execute the SQL statement: SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ':id' at line 1



Sorry, my fault. A second parameter for the find() method is used only when a first paramter is a string (like 'id = :id').
0

#18 User is offline   bettor 

  • Master Member
  • PipPipPipPip
  • Yii
  • Group: Members
  • Posts: 749
  • Joined: 02-February 09

Posted 11 January 2010 - 04:22 AM

excellent help. I will prepare a cookbook
0

#19 User is offline   gallego123 

  • Advanced Member
  • PipPipPip
  • Yii
  • Group: Members
  • Posts: 535
  • Joined: 11-August 09
  • Location:Argentina

Posted 11 January 2010 - 05:54 AM

View Postbettor, on 11 January 2010 - 04:22 AM, said:

excellent help. I will prepare a cookbook


very good help!
I hope this cookbook
thanks at all
KISS - Keep It Simple Stupid
ASAP-As Soon As Possible
http://www.yiiframew...oc/cookbook/71/
0

#20 User is offline   bas_vdl 

  • Standard Member
  • PipPip
  • Yii
  • Group: Members
  • Posts: 215
  • Joined: 01-April 09

Posted 11 January 2010 - 12:27 PM

What is wrong:

CDbCommand failed to execute the SQL statement: SQLSTATE[HY093]: Invalid parameter number: no parameters were bound

        echo $_GET['city']; //http://yii.dev/index/test/city/amsterdam.html prints amsterdam on the page
        $criteria = new CDbCriteria;
        $criteria->condition = 'City = :city';
        $city = City::model()->find($criteria, array(':city' => $_GET['city']));

0

Share this topic:


  • (2 Pages)
  • +
  • 1
  • 2
  • You cannot start a new topic
  • You cannot reply to this topic

1 User(s) are reading this topic
0 members, 1 guests, 0 anonymous users