$_GET validation question
#1
Posted 08 January 2010 - 02:48 PM
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.
#2
Posted 08 January 2010 - 02:59 PM

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"
#3
Posted 08 January 2010 - 03:51 PM

I found this $this->_GET..? what is this?
post comments here:
EXTENDING CRUD GENERATION (scaffolding)
old tentative released (module generator):
http://www.yiiframew...sion/modulegen/
#4
Posted 08 January 2010 - 04:45 PM
Quote
Why the use of parameters in the method find help?
Quote
Does that mean "escape user input"? a example?
Here is something, but only upon showing, not validate GET parameters
http://www.yiiframew...topics.security
#5
Posted 08 January 2010 - 05:29 PM
iGrog, on 08 January 2010 - 02:59 PM, said:

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
#6
Posted 09 January 2010 - 04:05 AM
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
#7
Posted 09 January 2010 - 08:54 AM
bettor, on 09 January 2010 - 04:05 AM, said:
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
#8
Posted 09 January 2010 - 10:20 AM
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.
#9
Posted 09 January 2010 - 10:54 AM
#10
Posted 09 January 2010 - 11:22 AM
Y!!, on 09 January 2010 - 10:20 AM, said:
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
#11
Posted 09 January 2010 - 11:48 AM
bettor, on 09 January 2010 - 11:22 AM, said:
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.
#12
Posted 09 January 2010 - 04:33 PM

post comments here:
EXTENDING CRUD GENERATION (scaffolding)
old tentative released (module generator):
http://www.yiiframew...sion/modulegen/
#13
Posted 10 January 2010 - 05:29 AM
Y!!, on 09 January 2010 - 11:48 AM, said:
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();
#14
Posted 10 January 2010 - 06:37 AM
example:
$criteria->condition="value = '".$_GET['id']."'";is this safe? Does Yii auto-bind the parameter in this case?
Thanks,
b
#15
Posted 10 January 2010 - 06:49 AM
bettor, on 10 January 2010 - 06:37 AM, said:
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)
#16
Posted 10 January 2010 - 07:48 AM
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
#17
Posted 10 January 2010 - 09:08 AM
bettor, on 10 January 2010 - 07:48 AM, said:
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').
#19
Posted 11 January 2010 - 05:54 AM
#20
Posted 11 January 2010 - 12:27 PM
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']));