最近因为需要将平台对外,需要考虑到安全性问题,于是又去研究了下关于Yii框架的安全特性。
Yii框架的安全特性主要体现在这几个方面:
- SQL注入的防范措施
- XSS的防范措施
- CSRF的防范措施
- COOKIE验证机制
- 访问控制过滤器
- 对
magic_quotes_gpc
的判断
SQL注入的防范措施
DB库提供了类似PDO库的绑定参数的函数bindParam
和bindValue
(函数原型都在CdbCommand.php
)。调用CDbCommand::bindParam()
或CDbCommand::bindValue()
以使用实际参数替换这些占位符。参数绑定必须在SQL语句执行之前完成。bindParam()
和bindValue()
非常相似。唯一的区别就是前者使用一个PHP变量绑定参数,而后者使用一个值。对于那些内存中的大数据块参数,处于性能的考虑,实际应用中通常会优先使用前者。
因此在对外上线前,审阅代码时,凡是遇到代码中使用了DB库的参数绑定函数bindParam
或bindValue
进行参数绑定的变量,都可以认为的安全的,不存在SQL注入漏洞,反之则可能存在,需要修改。
XSS的防范措施
本来为了防范XSS,特地去下载了HTMLPurifier放到代码中,对答题指南、题型设计等信息都进行白名单功能过滤恶意代码。
后来发现Yii本身就集成了HTMLPurifier
,并且为开发者提供了一个很有用的组件CHtmlPurifier
,这个组件封装了HTMLPurifier
。它可以将通过彻底的检查、安全和白名单功能来把所审核的内容中的所有的恶意代码清除掉,并且确保过滤之后的内容过滤符合标准。
CHtmlPurifier
组件可以作为一个widget或者filter来使用。当作为一个widget来使用的时候,CHtmlPurifier可以对在视图中显示的内容进行安全过滤。
CSRF防范措施
要防范CSRF攻击,必须遵守这样的规则:
- GET请求只允许检索数据而不能修改服务器上的任何数据。
- POST请求应当含有一些可以被服务器识别的随机数值,用来保证表单数据的来源和运行结果发送的去向是相同的。
因此需要注意代码中是否使用$_REQUEST
来获取表单提交的数据,(这将允许以GET请求替代POST请求),并且没有带上随机token。这样会产生CSRF漏洞。
Yii实现了一个CSRF防范机制,用来帮助防范基于POST的攻击。这个机制的核心就是在cookie中设定一个随机数据,然后把它同表单提交的POST数据中的相应值进行比较。
默认情况下,CSRF防范是禁用的。如果你要启用它,在应用配置中设置组件CHttpRequest
,如下代码示例:
return array(
'components'=>array(
'request'=>array(
'enableCsrfValidation'=>true,
),
),
);
COOKIE验证机制
Yii实现了一个cookie验证机制,可以防止cookie被修改。启用之后可以对cookie的值进行HMAC检查。Cookie验证在默认情况下是禁用的。如果要启用它,可以编辑应用配置中的组件中的CHttpRequest
部分。
return array(
'components'=>array(
'request'=>array(
'enableCookieValidation'=>true,
),
),
);
需要注意,这里一定要使用 Yii 提供的 cookie验证方案,也需要使用Yii内置的cookies集合来访问cookie,不可以直接使用$_COOKIES。否则此机制将不会起作用。
// 检索一个名为$name的cookie值
$cookie = Yii::app()->request->cookiees[$name];
$value = $cookie->value;
...
// 设置一个cookie
$cookie = new CHttpCookie($name, $value);
Yii::app()->request->cookies[$name] = $cookie;
访问控制过滤器
访问控制过滤器是检查当前用户是否能执行访问的controller的action的初步授权模式。这种授权模式基于用户名,客户IP地址和访问类型。
在控制器(controller)里重载CController::filters
方法设置访问过滤器来控制访问动作。
对magic_quotes_gpc
的判断
CHttpRequest
类是HTTP库中的一个重要功能类,其中的
normalizeRequest
函数会判断magic_quotes_gpc
是否开启,如果开启则使用stripSlashes
函数把$_GET
,$_POST
,$_REQUEST
,$_COOKIE
请求中被转义的部分取消转义。
代码原型如下:
if (function_exists('get_magic_quotes_gpc') && get_magic_quotes_gpc()) {
if(isset($_GET))
$_GET=$this->stripSlashes($_GET);
if(isset($_POST))
$_POST=$this->stripSlashes($_POST);
if(isset($_REQUEST))
$_REQUEST=$this->stripSlashes($_REQUEST);
if(isset($_COOKIE))
$_COOKIE=$this->stripSlashes($_COOKIE);
}
总结
Yii框架本身就提供了一些安全特性,我们应当在写代码时就注意规范,例如杜绝用户输入直接写入sql语句中,那么Yii框架就可以帮我们解决一些安全问题了。