Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/amazon-s3/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
PHP/Yii项目中的CSRF_Php_Security_Yii_Csrf - Fatal编程技术网

PHP/Yii项目中的CSRF

PHP/Yii项目中的CSRF,php,security,yii,csrf,Php,Security,Yii,Csrf,我有一个yii(php)项目,现在我想测试一下,它是否能够抵御csrf攻击 代码如下所示: if (!Yii::app()->request->isAjaxRequest)){ die("error"); } else { // Do stuff } 现在,如果我在Firebug中调用URL,它就会工作(“执行Do stuff”) 但是,如果我在浏览器中调用完全相同的URL,我会得到“error”,因为Yii::app()->request->isAjaxReques

我有一个yii(php)项目,现在我想测试一下,它是否能够抵御csrf攻击

代码如下所示:

if (!Yii::app()->request->isAjaxRequest)){
   die("error");
} else { 
   // Do stuff
}
现在,如果我在Firebug中调用URL,它就会工作(“执行Do stuff”)

但是,如果我在浏览器中调用完全相同的URL,我会得到“error”,因为Yii::app()->request->isAjaxRequest将为false

这是否意味着,我的应用程序可以安全地抵御CSRF攻击,或者是否有任何方法可以欺骗“Yii::app()->request->isAjaxRequest”使其认为这是一个真正的Ajax请求


多谢各位

简短回答:您误解了CSRF的含义

详细回答:CSRF是关于保护POST请求的,包括AJAX发出的请求。这是通过创建一个随机生成的令牌作为隐藏表单字段呈现在页面上完成的,它将该令牌添加到请求中,以便在处理表单的其余部分之前对其进行验证。如果要进行AJAX POST调用,则需要手动将CSRF令牌添加到请求中。当POST请求中缺少CSRF令牌时,框架抛出异常


isAjaxRequest
属性只是检查特定的http头。您不应该依赖它,也就是说,它不应该用于保护访问。

isAjaxRequest的代码如下所示:

public function getIsAjaxRequest()
{
    return isset($_SERVER['HTTP_X_REQUESTED_WITH']) && $_SERVER['HTTP_X_REQUESTED_WITH']==='XMLHttpRequest';
}
它似乎正在检查是否设置了HTTP头。这实际上是因为它是一个未经用户同意不能跨域发送的头文件。是的,具有的攻击者可以通过设置此标头来欺骗AJAX请求,但这在CSRF攻击中对他们没有好处,因为他们没有用户的Cookie来发送

这种方法的唯一缺点是,您只能使用它来保护来自CSRF的AJAX请求,而不是普通的web表单帖子,因为您无法使用这种机制设置标题


如果您需要保护web表单帖子,那么您需要实现一个解决方案,例如。这是您生成加密安全令牌服务器端并将其与用户会话关联的地方。然后在每个表单帖子上检查该键,因为它包含在隐藏的表单字段中。这可以防止CSRF,因为攻击者无法从页面读取令牌。

感谢您的回复。如果应用程序更改GET上的数据,也可以使用正常GET执行CSRF攻击。对于我发布的例子,有攻击向量吗?如果我把url(例如)放在一个标记中,并将其发送给一个登录的用户,我将得到“错误”。有没有办法绕过这项检查非常感谢。您应该避免使用GET来修改任何内容,这就是关键所在。否则,您还应该要求这些请求使用CSRF令牌。要回答您的问题,您必须修改请求头。这需要一些工具。在浏览器控制台中查看AJAX请求,看看现在的标题是什么样子。非常感谢您的回复。现在我明白了!
public function getIsAjaxRequest()
{
    return isset($_SERVER['HTTP_X_REQUESTED_WITH']) && $_SERVER['HTTP_X_REQUESTED_WITH']==='XMLHttpRequest';
}