大家好,又见面了,我是你们的朋友全栈君。
官方定义
CSRF(Cross-site request forgery跨站请求伪造,也被称成为“one click attack”或者session riding,通常缩写为CSRF或者XSRF,是一种对网站的恶意利用。尽管听起来像跨站脚本(XSS),但它与XSS非常不同,并且攻击方式几乎相左。XSS利用站点内的信任用户,而XSRF则通过伪装来自受信任用户的请求来利用受信任的网站。与XSS攻击相比,XSRF攻击往往不大流行(因此对其进行防范的资源也相当稀少)和难以防范,所以被认为比XSS更具危险性。
攻击通过在授权用户访问的页面中包含链接或者脚本的方式工作。例如:一个网站用户Bob可能正在浏览聊天论坛,而同时另一个用户Alice也在此论坛中,并且后刚刚发布了一个具有Bob银行链接的图片消息。设想一下,Alice编写了一个在Bob的银行站点上进行取款的form提交的链接,并将此链接作为图片tag。如果Bob的银行在cookie中保存他的授权信息,并且此cookie没有过期,那么当Bob的浏览器尝试装载图片时将提交这个取款form和他的cookie,这样在没经Bob同意的情况下便授权了这次事务。
XSRF是一种依赖web浏览器的、被混淆过的代理人攻击(deputy attack)。在上面银行示例中的代理人是Bob的web浏览器,它被混淆后误将Bob的授权直接交给了Alice使用。
下面是XSRF的常见特性:
- 依靠用户标识危害网站
- 利用网站对用户标识的信任
- 欺骗用户的浏览器发送HTTP请求给目标站点
风险在于那些通过基于受信任的输入form和对特定行为无需授权的已认证的用户来执行某些行为的web应用。已经通过被保存在用户浏览器中的cookie进行认证的用户将在完全无知的情况下发送HTTP请求到那个信任他的站点,进而进行用户不愿做的行为。
草根版本
简单的说,XSRF就是可以让黑客借用受害者的身份干点坏事。
比如,从你的银行账户上转点钱到他账户上(借用你的身份转账);创建系统账号(借用受信的管理员的身份创建帐号)等等。
为了实施XSRF,攻击这需要具备以下几个条件:
v???? 攻击者需要了解受害者所在的站点
对于公开的网站这一点不成问题,对于后台管理系统,不同管理员间的欺骗也有可能发生,甚至管理系统的原开发团队别有用心的成员也有可能发动对系统的攻击。
v???? 攻击者的目标站点具有持久化的授权cookie或是当前会话Cookie。
很多公开站点拥有“记住我”功能,用户往往也非常喜欢这样的功能,攻击者还可以使用欺诈的办法诱导受害者登陆以便拥有当前会话Cookie。对于后台管理系统,一般操作员在工作时间始终保持登陆状态,攻击者很容易利用当前会话Cookie发动攻击。
v???? 目标站点没有对用户动作进行二次授权。
由于XSRF不怎么明显,所以大多数网站并没有进行很好的防御,甚至像Baidu这样的大型互联网企业的网站都没有进行针对的防范。
根据上面的分析,攻击条件实际上是很容易满足的。所以XSRF的危害非常大,而且实施难度也比较低。
比如在系统中有一个这样的表单:
<form action=”adminManage.jsp”>
<input type=”hidden” name=”action” value=”add”/>
<input type=”text” name=”name” value=””/>
<input type=”password” name=”password” value=””/>
<input type=”submit” value=”Create”/>
</form>
最简单的攻击方式是直接发送一个执行系统某个操作的链接给受害者,比如:
此时,假如受害者打开这个页面,实际上他就执行了创建管理员的动作。这显然不是他想要的。
当然上面的攻击方式很明显,很容易被受害者发现,不过攻击者也一般都很聪明的。他可以使用短域名服务来对上面的攻击地址进行处理,让管理员看不出什么是做什么用的连接,当然还是不够Smart,因为浏览器会停留在创建管理员成功的页面。
那么这样呢?
<img src=”” width=0 height=0/>
当受害者打开包含这样代码的页面的时候,在不知不觉中,一个管理员被创建了。受害者不会有任何感觉。
上面的攻击方式都有一个共同点,就是系统接受GET请求。现在我们深入一步,使用POST。
使用POST最简单的方式是发动第三方站点参与攻击,攻击者诱骗受害者打开污染的页面,污染的页面里的JavaScript强制提交一个攻击者伪造的表单,同样实现了XSRF攻击的效果。
比如:
<form id=”form” action=”http://xxx.com/admin/adminManage.jsp”>
<input type=”hidden” name=”action” value=”add”/>
<input type=”text” name=”name” value=”hello”/>
<input type=”password” name=”password” value=”world”/>
<input type=”submit” value=”Create”/>
</form>
<script type=”text/javascript”>
document.getElementById(“form”).submit());
</script>
这样的一个页面很简单的就实现了针对漏洞系统的XSRF攻击。为了更隐蔽,黑客可以用CSS把表单隐藏起来。甚至更隐蔽一些,把整个攻击页面用IFRAME嵌入到正常页面中,同时把IFRAME的宽高设置为0。
XSRF通常还会和XSS结合来进行更高级的攻击,甚至可以创建在网站上自动传播的蠕虫病毒,而采用的技术却非常简单。这部分攻击技术比较复杂,不在这里讨论。
要防范XSRF攻击,当然是要想办法让黑客没法满足实施攻击的条件,返回去看XSRF攻击的条件及分析,显然,我们只能从第三点入手。为了方便理解防范XSRF攻击的原理,这里举一个极端的例子:我们在每一个业务动作中要求用户登录。这样就彻底的杜绝了XSRF。但是问题也很明显,用户根本无法接受,可用性太差了。
防范XSRF的核心思想就是用一个黑客得不到的变量来做二次认证,比如让用户登录,黑客是不能轻易拿到别人的用户名密码的。
防范XSRF,我们需要实施的具体措施包括:
1、??????????????? 严格过滤用户输入,慎重处理信息显示输出。防范Injection/XSS漏洞的产生。如果一个网站存在XSS漏洞,很难甚至是几乎不可能保证它不存在XSRF漏洞。
2、??????????????? GET方法只用于读取和显示数据,所有的需要向服务器提交数据或修改数据的请求一律使用POST方法。使用POST方法不能防范XSRF,但是会提高攻击的门槛。而且也更符合HTTP/HTML的语义以及RFC2616的推荐规范。
3、??????????????? 最重要的,在所有的POST数据中添加一个不可预知的参数。可以是一个随机数,或是时间相关的HASH值,或是其他不可预知的值,通常称为Token。Token必须和会话绑定,Token可以保存到Cookie或是Session中。每一个POST动作中比较提交上来的Token参数和与会话绑定的Token值是否匹配,以确定是否为合法请求。
For java Applications
Diagram.1
对于java应用来说,我们在业务和页面展现之间加入个AntiXSRFFilter,对每一个请求生成Token(也可以共享Token),对每一个业务动作(POST)验证Token参数合法性,就可以实现XSRF的防范。对于以前未进行防范的应用,首先需要修改以便保证所有的业务动作只接受POST请求,然后修改每一个表单,在表单中加入Token参数。
For .NET Applications
Read
ASP.NET 的ViewState可以被加密,达到防CSRF的目的。具体参见上面链接。
原文链接:http://www.qiyeku.com/xinwen/699638.html
发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/144294.html原文链接:https://javaforall.cn