CSRF攻击与防御
CSRF(Cross-Site Request Forgery)是指跨站请求伪造,也常常被称为“One Click Attack”或者“Session Riding”,通常缩写为CSRF或是XSRF。
1 原理
CSRF攻击攻击原理及过程如下:
-
用户C打开浏览器,访问受信任网站A,输入用户名和密码请求登录网站A;
-
在用户信息通过验证后,网站A产生Cookie信息并返回给浏览器,此时用户登录网站A成功,可以正常发送请求到网站A;
-
用户未退出网站A之前,在同一浏览器中,打开一个TAB页访问网站B;
-
网站B接收到用户请求后,返回一些攻击性代码,并发出一个请求要求访问第三方站点A;
-
浏览器在接收到这些攻击性代码后,根据网站B的请求,在用户不知情的情况下携带Cookie信息,向网站A发出请求。网站A并不知道该请求其实是由B发起的,所以会根据用户C的Cookie信息以C的权限处理该请求,导致来自网站B的恶意代码被执行。
2 检测CSRF漏洞
检测CSRF攻击主要分为两种,手工检测和半自动检测。
2.1 手工检测
在检测CSRF漏洞时,首先需要确定的一点是:CSRF只能通过用户的正规操作进行攻击,实际上就是劫持用户操作。所以,在检测前首先需要确定Web应用程序的所有功能,以及确定哪些操作是敏感的,比如修改密码、转账、发表留言等功能。
确定了敏感性操作后,使用这项“功能”拦截HTTP请求,比如,删除用户操作URL为:
Http://www.xxxxx.com/delUser.action?id=1
,可以猜想,此时的参数项ID应该是用户的唯一标识信息,通过此ID可以删除指定的用户。在确定参数项的意义后,就可以验证该项功能是否存在CSRF漏洞。
<html>
<body>
<from name="myfrom" action="delUser.action" method="GET">
<input type="hidden" name="id" value="5" />
</from>
<script>
var myfrom = document.getElementById("myfrom");
myfrom.submit();
</script>
</body>
</html>
打开这个HTML,JavaScript将会自动提交这个form表单,当提交请求后,查看ID为5的用户是否已经被删除,如果被删除,就可以确定存在CSRF漏洞。
CSR漏洞也可以理解为:服务器到底有没有执行POC的请求,如果已执行,则代表存在CSRF漏洞。
2.2 半自动检测
CSRF漏洞最常用的是半自动检测,工具有CSRFTester、CSRF Request Builder等。
CSRFTester如图所示:
CSRFTester启动之后,将会在run.bat控制台中看到如下字符:
这表示CSRFTester已经在监听8008端口,如果想要使用CSRFTester,就必须将浏览器的代理端口设置为8008端口。
登录要检测的网站后,在测试某项功能是否存在CSRF漏洞之前,单击“Start Recording”
按钮开启CSRFTester的检测工作。此时再访问网站,所有的请求URL都会被 CSRFTester—一记录下来。
3 CSRF攻击
3.1 GET
最简单的CSRF攻击:
- 用户Alice登录访问某有csrf漏洞的银行网站
http://www.examplebank.com。
- Alice被某些信息诱导访问危险网站B。
- 危险网站B上有一个
<img>
标签 <img src="http://www.examplebank.com/from=Alice&amount=100&to=Bob">
- 这个img标签的src不指向图片,而是一个http请求,这个请求让银行服务器从Alice转100到Bob账户上,由于Alice已经登录,浏览器发请求时候会带上cookie骗取服务器信任得到响应。
- 这样Alice的钱就被悄悄转走了。
<a href="http:xxx.com/xxx">点击</a>
<img src="http:xxx.com/xxx">
网络蠕虫。
涉及敏感操作的请求改为POST请求。
3.2 POST
危险网站伪造一个隐藏的<from>
表单,在onload事件中,触发表单的提交事件。
为防止跳转,可以加一个隐藏的iframe,在iframe中处理提交的请求。
<script>
document.write(`
<from name="commentFrom" target="csrf"
method="post" action="http://localhost:1234/post/addComment">
<input name="postId" type="hidden" value="13">
<textarea name="content">来自CSRF!</textarea>
</from>`
);
var iframe = document.createElement(‘iframe’);
iframe.name='csrf';
iframe.style.display='none';
domcument.body,appendChild(iframe);
setTimeout(function(){
domcument.querySelector(`[name=commentForm]`).submit();
},1000);
</script>
4 CSRF防御
1、重要数据交互采用POST进行接收,当然是用POST也不是万能的,伪造一个form表单即可破解
2、使用验证码,只要是涉及到数据交互就先进行验证码验证,这个方法可以完全解决CSRF。但是出于用户体验考虑,网站不能给所有的操作都加上验证码。因此验证码只能作为一种辅助手段,不能作为主要解决方案。
3、为每个表单添加令牌token并验证
4、二次确认
在调用某些功能时进行二次验证,如:删除用户时,产生一个提示对话框,提示“确定删除用户吗?”。转账操作时,要求用户输入二次密码。
当二次验证后,即使用户打开了CSRF POC页面,也不会直接去执行,而需要用户再次输入才可以完成攻击。这样,当用户突然收到提示后,可能会心存怀疑,就不再会乖乖地中招。