YII CSRF屏蔽

文章开始先简单说说CSRF攻击,下面是引用百度百科。

CSRF(Cross-site request forgery跨站请求伪造,也被称为“one click attack”或者session riding,通常缩写为CSRF或者XSRF,是一种对网站的恶意利用。尽管听起来像跨站脚本(XSS),但它与XSS非常不同,并且攻击方式几乎相左。XSS利用站点内的信任用户,而CSRF则通过伪装来自受信任用户的请求来利用受信任的网站。与XSS攻击相比,CSRF攻击往往不大流行(因此对其进行防范的资源也相当稀少)和难以防范,所以被认为比XSS更具危险性。

CSRF攻击是一种常见的攻击,单独写代码仿CSRF攻击很费时,如果使用YII框架的话,这些工作框架就帮你完成了。YII开启防御CSRF很简单,配置一句代码整个项目就都有了防御CSRF的功能。今天我要说的是YII框架中没有的。CSRF默认是整个项目开启,而我们实际开发中会遇到一些功能不需要CSRF验证。所以得想办法让某些控制器屏蔽CSRF。

一.YII开启防御CSRF攻击功能
你只需要在YII配置文件中加上 ‘request’=>array( ‘enableCsrfValidation’ => true),然后在前端的form表单中添加一句,之后就再也不用担心CSRF攻击,至于原理,改天我专门写篇文章来说说。

二.YII屏蔽CSRF功能
YII如果开启CSRF默认是整个项目开启,但是某些时候我们根据业务的需求,需要在一些地方用CSRF一些地方不用。所以这件事情就比较棘手了。下面说说解决办法。

YII的CSRF功能开启后,默认调用的CHttpRequest控制器中的方法,我们要修改CSRF的验证功能就需要覆盖CHttpRequest中的normalizeRequest方法,具体代码如下。

新建一个类HttpRequest:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
class HttpRequest extends CHttpRequest  
{
public $noCsrfValidationRoutes=array();

protected function normalizeRequest()
{
//attach event handlers for CSRFin the parent
parent::normalizeRequest();
//remove the event handler CSRF if this is a route we want skipped
if($this->enableCsrfValidation)
{
$url=Yii::app()->getUrlManager()->parseUrl($this);
$t = strpos($url,"/");
if($t!==FALSE)
{
$url = substr($url,0,$t);
if(in\_array($url,$this->noCsrfValidationRoutes))
Yii::app()->detachEventHandler('onBeginRequest',array($this,'validateCsrfToken'));
}
}
}
}

修改配置文件

1
2
3
4
5
6
7
8
9
'request'=>array(   
// Enable Yii Validate CSRF Token
'enableCsrfValidation' => true,
'class'=>'HttpRequest',
'noCsrfValidationRoutes'=>array(
'admincontent',
),
'csrfTokenName'=>'csrf\_token'
),

最后我们就成功的将admincontent控制器绕过了CSRF的验证机制。没装代码可视化插件,看着有些痛苦……