CSRF漏洞原理说明与利⽤⽅法
翻译者:Fireweed
⼀、什么是CSRF
Cross-Site Request Forgery(CSRF),中⽂⼀般译作跨站请求伪造。经常⼊选owasp漏洞列表Top10,在当前web漏洞排⾏中,与XSS和SQL注⼊并列前三。与前两者相⽐,CSRF相对来说受到的关注要⼩很多,但是危害却⾮常⼤。
通常情况下,有三种⽅法被⼴泛⽤来防御CSRF攻击:验证token,验证HTTP请求的Referer,还有验证XMLHttpRequests⾥的⾃定义header。鉴于种种原因,这三种⽅法都不是那么完美,各有利弊。
⼆、 CSRF的分类
在跨站请求伪造(CSRF)攻击⾥⾯,攻击者通过⽤户的浏览器来注⼊额外的⽹络请求,来破坏⼀个⽹站会话的完整性。⽽浏览器的安全策略是允许当前页⾯发送到任何地址的请求,因此也就意味着当⽤户在浏览他/她⽆法控制的资源时,攻击者可以控制页⾯的内容来控制浏览器发送它精⼼构造的请求。
1、⽹络连接。例如,如果攻击者⽆法直接访问防⽕墙内的资源,他可以利⽤防⽕墙内⽤户的浏览器间接
的对他所想访问的资源发送⽹络请求。甚⾄还有这样⼀种情况,攻击者为了绕过基于IP地址的验证策略,利⽤受害者的IP地址来发起他想发起的请求。
2、获知浏览器的状态。当浏览器发送请求时,通常情况下,⽹络协议⾥包含了浏览器的状态。这其中包括很多,⽐如cookie,客户端证书或基于⾝份验证的header。因此,当攻击者借助浏览器向需要上述这些cookie,证书和header等作验证的站点发送请求的时候,站点则⽆法区分真实⽤户和攻击者。
3、改变浏览器的状态。当攻击者借助浏览器发起⼀个请求的时候,浏览器也会分析并相应服务端的response。举个例⼦,如果服务端的response⾥包含有⼀个Set-Cookie的header,浏览器会相应这个Set-Cookie,并修改存储在本地的cookie。这些改动都会导致很微妙的攻击,我们将在第三部分描述。
作⽤范围内的威胁:我们按照产⽣危害的⼤⼩将此部分分成三种不同的危害模型。
1、论坛可交互的地⽅。很多⽹站,⽐如论坛允许⽤户⾃定义有限种类的内容。举例来说,通常情况下,⽹站允许⽤户提交⼀些被动的如图像或链接等内容。如果攻击者让图像的url指向⼀个恶意的地址,那么本次⽹络请求很有可能导致CSRF攻击。这些地⽅都可以发起请求,但这些请求不能⾃定义HTTP header,⽽且必须使⽤GET⽅法。尽管HTTP协议规范要求请求不能带有危害,但是很多⽹站并不符合这⼀要求。
2、Web攻击者。在这⾥web攻击者的定义是指有⾃⼰的独⽴域名的恶意代理,⽐如attacker,并且拥有attacker的HTTPS证书和web服务器。所有的这些功能只需要花10美元即可以做到。⼀旦⽤户访问attacker,攻击者就可以同时⽤GET和POST⽅法发起跨站请求,即为CSRF攻击。
3、⽹络攻击者。这⾥的⽹络攻击者指的是能控制⽤户⽹络连接的恶意代理。⽐如,攻击者可以通过控制⽆线路由器或者DNS服务器来控制⽤户的⽹络连接。这种攻击⽐web攻击需要更多的资源和准备,但我们认为这对HTTPS站点也有威胁。因为HTTPS站点只能防护有源⽹络。
作⽤范围外的威胁:下⾯我们还列出了⼀些不在本论⽂讨论范围的相关危害模型。对这些危害的防御措施可以与CSRF的防御措施形成很好的互补。
1、跨站脚本(XSS)。如果攻击者能够向⽹站注⼊脚本,那么攻击者就会破坏该⽹站⽤户会话的完整性和保密性。有些XSS攻击需要发起⽹络请求,⽐如将⽤户银⾏账户⾥的钱转移到攻击者的账户⾥,但是通常情况下,对CSRF的防御并没有考虑到这些情况。考虑到更安全的做法,⽹站必须实现对XSS和CSRF的同时防御。
2、恶意软件。如果攻击者能够在⽤户的电脑上运⾏恶意软件,那么攻击者就可以控制⽤户的浏览器向那些可信的⽹站注⼊脚本。这时候基于浏览器的防御策略将会失效,因为攻击者可以⽤含有恶意插件的浏览器来替换⽤户的浏览器。
3、DNS的重新绑定。像CSRF⼀样,DNS重新绑定可以使⽤⽤户的IP地址来连接攻击者指定的服务器。处在防⽕墙保护内的服务器或者那些基于IP地址验证的服务器需要⼀个对抗DNS重新绑定的防御⽅案。尽管DNS重新绑定的攻击和CSRF攻击的意图⾮常相似,但是他们还是需要各⾃不同的解决⽅案。⼀个简单的解决DNS重新绑定攻击的⽅案就是要验证主机的HTTP请求header,确保包含有预期值。还有⼀个替代⽅案就是过滤DNS流量,防⽌将外部的DNS名称解析成内部私有地址。
4、证书错误。如果⽤户在出现HTTPS证书错误的时候还愿意继续点击访问,那么HTTPS能够提供的很多安全保护就没有意义。有⼀些安全研究者指出了针对这⼀种情况的威害,但是在本⽂中,我们假设⽤户不会在出现了HTTPS证书错误之后继续点击访问。
5、钓鱼。当⽤户在访问钓鱼⽹站的时候,在⾝份验证的时候输⼊个⼈信息,钓鱼攻击就发⽣了。钓鱼攻击现今⾮常普遍也很有效,因为⽤户有的时候真的很难区分钓鱼⽹站和真正的⽹站。
6、⽤户跟踪。⼀些合作⽹站会利⽤跨站请求来对⽤户的浏览习惯建⽴⼀个关联⾏为库。⼤多数浏览器都通过组织第三⽅cookie发送来阻⽌类似的跟踪,但是利⽤挂站请求,浏览器的这⼀特性可以被绕过。
三、登录CSRF
⽆论是利⽤浏览器的⽹络连接还是利⽤浏览器的状态,⼤多数对CSRF的讨论都集中在能改变服务端状
态的请求上⾯。尽管CSRF攻击能通过改变浏览器的状态来对⽤户在访问可信⽹站时候造成危害,但是对它的重视程度还是不够。再登陆CSRF攻击⾥⾯,攻击者利⽤⽤户在可信⽹站的⽤户名和密码来对⽹站发起⼀个伪造请求。⼀旦请求成功,服务器端就会响应⼀个Set-Cookie的header,浏览器接收到以后就会建⽴⼀个session cookie,并记录⽤户的登陆状态。这个session cookie被⽤作绑定后续的请求,因⽽也可被攻击者⽤来作为⾝份验证。依据不同的⽹站,登陆CSRF攻击还可以造成很严重的后果。
搜索记录:包括⾕歌和雅虎等很多搜索引擎允许他们的⽤户选择是否同意保存他们的搜索记录,并且为⽤户提供⼀个接⼝来查看他们⾃⼰的私⼈搜索记录。搜索请求⾥⾯包含了⽤户的⾏为习惯和兴趣的⼀些敏感细节,攻击者可以利⽤这些细节来欺骗⽤户,盗窃⽤户的⾝份或者窥探⽤户。当攻击者以⽤户⾝份登陆到搜索引擎⾥,就可以看到⽤户的搜索记录。如图1. 这样,⽤户的搜索查询记录就被存储到了攻击者的搜索记录⾥,攻击者就可以登陆⾃⼰的账户随便查询⽤户的搜索记录。
图1. 登陆CSRF攻击事件的跟踪图。受害⼈访问攻击者的⽹站,攻击者向⾕歌伪造⼀个跨站点请求的登陆框,造成受害者被攻击者登陆到⾕歌。随后,受害者使⽤搜索的时候,搜索记录就被攻击者记录下来。
PayPal:PayPal允许它的⽤户相互之间任意转移资⾦。转移资⾦的时候,⽤户要注册信⽤卡或者银⾏账户。攻击者可以利⽤登陆CSRF来发起以下攻击:
1、受害者访问了恶意商家的⽹站,并选择使⽤PayPal⽀付。
2、受害者被重定向到PayPal并且要求登陆他/她的账户。
3、⽹站等待⽤户登陆他/她的PayPal账户。
4、付款的时候,受害者先是登记⾃⼰的信⽤卡,但是信⽤卡实际上已经被添加到恶意商家的PayPal账户。
iGoogle:⽤户可以通过使⽤iGoogle来定制⾃⼰的⾕歌主页,也包括⼀些插件。为了易⽤性,这些插件是“嵌⼊到iGoogle的”,这也就意味着他们将影响到iGoogle的安全。通常情况下,iGoogle在添加新插件的时候,都会询问⽤户做出信任决定。但是攻击者可以通过登录CSRF攻击来帮助⽤户做出决定,从⽽安装任意的插件。
1、攻击者通过⽤户的浏览器授权安装⼀个iGoogle插件(含有恶意脚本),并将插件添加到⽤户的定制化iGoogle主页。
2、攻击者使⽤户登陆⾕歌,并开⼀个到iGoogle的框架。
4、攻击者现在可以:(a)在正确的URL页⾯构造⼀个登陆框(b)盗取⽤户⾃动填充的密码(c)在另⼀个窗⼝等待⽤户登陆并读取kie。
我们已经将上述漏洞告知了⾕歌,他们已经在两⽅⾯来减缓漏洞带来的危害。⾸先,⾕歌已经弃⽤内嵌的插件并禁⽌开发者开发类似的插件,只允许少部分⽐较受欢迎的内嵌插件。其次,⾕歌已经开发了私密token策略来防御登陆CSRF(下⾯将会讨论),但是这个策略只对登陆了的⽤户才有效。我们预计,⾕歌⼀旦充分测试了他们的防御⽅案并觉得有效之后,会否认他们的登陆CSRF漏洞。
四、现有的CSRF防御⽅案
⼀般⽹站有三种防御CSRF攻击的⽅案。(1)验证token值。(2)验证HTTP头的Referer。(3)⽤XMLHttpRequest附加在header⾥。以上三种⽅法都在⼴泛使⽤,但是他们的效果都不是那么的令⼈满意。
4.2 Token验证
在每个HTTP请求⾥附加⼀部分信息是⼀个防御CSRF攻击的很好的⽅法,因为这样可以判断请求是否已经授权。这个“验证token”应该不能轻易的被未登录的⽤户猜测出来。如果请求⾥⾯没有这个验证token或者token不能匹配的话,服务器应该拒绝这个请求。
Token验证的⽅法可以⽤来防御登陆CSRF,但是开发者往往会忘记验证,因为如果没有登陆,就不能通过session来绑定CSRF token。⽹站要想⽤验证token的⽅式来防御登陆CSRF攻击的话,就必须先创建⼀个“前session”,这样才能部署CSRF的防御⽅案,在验证通过了之后,再创建⼀个真正的session。
Token的设计。有很多技术可以⽣成验证token。
• session标识符。浏览器的cookie存储⽅式就是为了防⽌不同域之间互相访问cookie。⼀个普遍的做法是直接利⽤⽤户的session标识符来作为验证token。服务器在处理每⼀个请求时,都将⽤户的token与session标识符来匹配。如果攻击者能够猜测出⽤户的token,那么他就能登录⽤户的账户。⽽且这样做有个不好的地⽅在于,偶尔⽤户正在浏览的内容会发送给第三⽅,⽐如通过电⼦邮件直接上⽹页内容上传到浏览器⼚商的bug跟踪数据库。如果正好这个页⾯包含有⽤户的session标识符,任何能看到这个页⾯的⼈都能模拟⽤户登陆到⽹站,直到会话过期。
• 独⽴session随机数。与直接使⽤⽤户的session标识符不⼀样的是,当⽤户第⼀次登陆⽹站的时候,服务器可以产⽣⼀个随机数并将它存储在⽤户的cookie⾥⾯。对于每⼀个请求,服务器都会将token与存储在cookie⾥的值匹配。例如,⼴泛使⽤的Trac问题跟踪系统就是⽤的此技术。但是这个⽅法不能防御主动的⽹络攻击,即使是整个web应⽤都使⽤的是HTTPS协议。因为攻击者可以使⽤他⾃⼰的CSRF token 来覆盖来覆盖这个独⽴session随机数,进⽽可以使⽤⼀个匹配的token来伪造⼀个跨站请求。
• 依赖session随机数。有⼀个改进产⽣随机数的⽅法是将⽤户的session标识符与CSRF token建⽴对应关系后存储在服务端。服务器在处理请求的时候,验证请求中的token是否与session标识符匹配。这个⽅法有个不好的地⽅就是服务端必须要维护⼀个很⼤的对应关系表(哈希表)。
• session标识符的HMAC。有⼀种⽅法不需要服务端来维护哈希表,就是可以对⽤户的session token做⼀个加密后⽤作CSRF 的token。例如, Ruby on Rails的web程序⼀般都是使⽤的这种⽅法,⽽且他们是使⽤session标识符的HMAC来作为CSRF token的。只要所有的⽹站服务器都共享了HMAC密钥,那么每个服务器都可以验证请求⾥的CSRF token 是否与session标识符匹配。HMAC的特性能确保即使攻击者知道⽤户的CSRF token,也不能推断出⽤户的session标识符。
鉴于有充⾜的资源,⽹站都可以使⽤HMAC⽅法来防御CSRF攻击。但是,很多⽹站和⼀些CSRF的防御框架(⽐如NoForge, CSRFx 和CSRFGuard)都不能正确的实现⽐较隐秘的token防御。⼀个常见的错误就是在处理跨站请求的时候暴露了CSRF token。举个例⼦,⼀个可信的⽹站在对另⼀个⽹站发起请求的时候附加上了CSRF token,那么那个⽹站就可以对这个可信的⽹站伪造⼀个跨站请求。
案例研究:NoForge.NoForge就是使⽤服务端保存哈希表的⽅式来验证⽤户的CSRF token。它在所有链接和表单提交的时候会附加⼀个CSRF token,造成这种技术不太完善的原因有以下三个:
1、HTML是在浏览器⾥动态创建的,⽽不会被重新加上CSRF token。有些⽹站是在客户端创建HTML的。⽐如Gmail, Flickr, 和 Digg都是⽤JavaScript 来创建表单,⽽这些表单正是需要CSRF防御措施的。
2、NoForge并没有对指向本站和外站的超链接作区分。如果有⼀个指向外站的超链接,那么外站可以⽤请求⾥⾯获取到⽤户的
CSRF token。⽐如,如果phpBB部署了NoForge,那么⼀旦⽤户点击了⼀个连接,连接的站点就可以获取到⽤户的CSRF token,即使NoForge区分了是本站的链接还是外站的链接,因为Referer 还是会暴露⽤户的CSRF token。
3、NoForge对登陆CSRF并没有什么效果,因为如果⽤户已经有了session标识符(登陆了),那么NoForge只会验证CSRF token。尽管这种缺陷是可以修复,但是这也说明了要想正确的实施token验证策略并不是⼀件很容易的事情。
虽然上述三个原因都是可以修复的,但是这些缺陷都说明了要想正确地实施token验证策略,是很复杂的⼀件事情。
CSRFx 和 CSRFGuard,还有很多⽹站都说明了这⼀问题。
4.2 Referer
⼤多数情况下,当浏览器发起⼀个HTTP请求,其中的Referer标识了请求是从哪⾥发起的。如果HTTP头⾥包含有Referer的时候,我们可以区分请求是同域下还是跨站发起的,因为Referer离标明了发起请求的URL。⽹站也可以通过判断有问题的请求是否是同域下发起的来防御CSRF攻击。
不幸的是,通常Referer会包含有⼀些敏感信息,可能会侵犯⽤户的隐私。⽐如,Referer可以显⽰⽤户
对某个私密⽹站的搜索和查询。尽管这些内容对私密⽹站站长来说是好事,因为他们可以通过这些内容来优化搜索引擎排名,但是⼀些⽤户还是认为侵犯了他们的隐私。另外,许多组织也很担忧Referer可能会将内⽹的⼀些机密信息泄露出去。
漏洞。从历史上来看,浏览器的⼀些漏洞使得⼀些恶意⽹站有欺骗Referer的价值,尤其是在使⽤代理服务器的时候。很多对Referer欺骗的讨论都标明浏览器允许Referer可以伪造。Mozilla在Fire-fox 1.0.7⾥⾯已经修复了Referer欺骗的漏洞。⽬前的IE则还有这⽅⾯的漏洞,但是这些漏洞只能影响XMLHttpRequest,并且只能⽤来伪造Referer跳转到攻击者⾃⼰的⽹站。
尺度。如果⽹站选择使⽤Referer来防御CSRF攻击的话,那么⽹站的开发⼈员就需要决定到底是使⽤⽐较宽松还是⽐较严格的Referer验证策略。如果采⽤宽松的Referer验证策略,⽹站就应该阻⽌Referer值不对的请求。如果请求⾥⾯没有Referer,就接收请求。尽管这个⽅法⽤的很普遍,但是它很容易被绕过。因为攻击者可以在header⾥⾯去掉Referer。例如,FTP和数据URL发起的请求⾥⾯就不包含Referer。如
果使⽤严格的Referer验证策略,⽹站还要阻⽌没有Referer的请求。这样做主要是为了防⽌恶意⽹站主动隐藏Referer,但也会带来兼容性问题,⽐如会误杀⼀部分合法的请求,因为有些浏览器和⽹络的设置默认就是不含有Referer的。所以说这个度⼀定要掌握好,很多时候取决于经验。我们还会在4.2.1⾥讨论这个问题。
4.2.1 实验
为了评估严格的Referer验证策略的兼容性,我们进⾏了⼀项实验来衡量到底有多⼤概率以及在什么情况下,合法的请求⾥⾯不含有Referer。
设计。⼴告是⼀个很⽅便测量浏览器和⽹络特征的渠道,因此我们可以利⽤⼴告作为实验平台。在2008年4⽉5⽇到4⽉8⽇期间,我们从163,767个独⽴IP购买了283,945 个⼴告,分别是两个不同的⼴告渠道。在渠道A,我们以每千次展⽰0.50美元的价格购买了⽹络旗帜⼴告,关键字为“⽕狐”,“游戏”,“IE”,“视频”,“YouTube”。在渠道B,我们以每千次展⽰5美元的价格的间隙⼴告,关键字为“芭蕾”,“⾦
融“,“花”,“⾷品”和“园艺”。我们在每个⼴告渠道上花了100美元,渠道A有241,483点击量(146,310个独⽴IP),渠道B有42,406点击量(18,314个独⽴IP)。
⼴告服务是由我们实验室⾥的两台主机提供,两个独⽴的域名是从不同的注册商处购买。每当显⽰⼴告时,⼴告会在接下来的每个请求⾥⾯⽣成⼀个特定的标识符,并随机选择⼀台主机作为主服务器。主服务器通过HTTP或者HTTPS协议将客户端HTML发送到我们的服务器,这些HTML能发起⼀个GET或者POST请求。其中,请求包括提交表单,图像请求和XMLHttpRequests。请求的顺序是随机的并且跟⽤户的操作⽆关。当⼴告通过了浏览器的安全策略之后,就向主服务器发起⼀个同域的请求,同时向次服
务器发起⼀个跨域请求。每个服务器的成本是400美元,域名是7美元,从⼀个合法的证书颁发机构获得的90天域验证的HTTPS证书是免费的。服务器根据接收到的⽹络请求来记录请求参数,包括Referer,User-Agent头,⽇期,客户端的C类⽹络,会话标识符。服务器还通过DOM API记录了ferrer的值,但是不记录客户端的IP地址。为了统计独⽴的IP地址,服务器利⽤⼀个随机产⽣的KEY⽽不是记录HMAC的⽅式,这个KEY会被丢弃。服务器记录的信息不⾜以单独确定⼴告的浏览者到底有多少。
伦理。实验的设计遵守两个⼴告渠道的规则。实验中的⾏为基本上都是web⼴告每天的⾏为,所以都能正常的从⼴告商那⾥请求额外的资源,⽐如图⽚,⾳频和视频。尽管我们的⼴告产⽣的HTTP请求数⽬远⼤于普通的⼴告,但是我们需要的带宽明显⽐⼀个视频⼴告需要的带宽要⼩。我们的服务器也像⼴告商⼀样,只记录他们所记录的信息。实际上我们的服务器记录的信息明显要⽐商业的⼴告商要少,因为我们并不记录客户端的IP地址。
结果。我们已经将结果在图2和图3⾥总结出来了,我们还发现以下结果只有95%的可信度。
• HTTP⽅法⾥,跨域请求⽐同域请求不包含Referer头的情况更普遍,⽽在POST⽅法(卡⽅系数= 2130, p值<0.001) 和GET⽅法(卡⽅系数= 2175, p值<0.001) ⾥⽐较,前者不包含Referer头的情况更为普遍。
• 在不包含Referer头的统计中,HTTP⽐HTTPS更为普遍,包括跨域POST(卡⽅系数= 6754, p值<0.001)
请求,跨域GET(卡⽅系数= 6940, p 值<0.001)请求,同域POST(卡⽅系数= 2286, p值<0.001)请求和同域GET请求(卡⽅系数= 2377, p值<0.001)。
• 在不包含Referer头的统计中,⼴告渠道B所有形式的请求都⽐A要更普遍。这些请求形式包括:HTTP跨域POST(卡⽅系数= 3060, p值
<0.001),HTTP同域POST(卡⽅系数= 6537, p值<0.001),HTTPS跨域POST(卡⽅系数= 49.13, p值<0.001)和HTTPS同域POST(卡⽅系数= 44.52, p值<0.001)请求。
• 我们还统计了⾃定义的header X-Requested-By(参见4.3节)和Origin(见第5章),X-Requested-By⼤概有0.029%到0.047%的
HTTP POST请求,0.084%到0.112%的HTTP GET请求,0.008%到0.018%的HTTPS POST请求和 0.009%到0.020%的HTTPS GET请求⾥不包含有Referer头。Origin则在与上述相同的请求⾥都不包含Referer头。
图2. 不包含Referer和Referer不正确的请求(283,945 个结果)。x和y分别代表主服务器和次服务器的域名
讨论。下⾯有两个有⼒的证据可以表明在不包含Referer的请求⾥,通常是来⾃⽹络(攻击)⽽不是浏览器。
1、HTTP请求⽐HTTPS请求不包含Referer更为普遍是因为,⽹络代理可以删除HTTP请求⾥的header,但是不能删除HTTPS请求⾥的header。当然,在⼀些企业的⽹络⾥,⼀些HTTPS的终端就是⼀个⽹络代理,这种情况下代理可以修改HTTPS请求,但是这种情况是⽐较罕见的。
2、浏览器在去掉Referer的时候也会去掉ferrer的值,但是如果Referer是在⽹络⾥去掉的话,ferrer却还在。但是我们发现,Referer去掉的情况⽐ferrer去掉的情况要更为普遍。
html实现用户注册登录代码实际上,在实验中,ferrer值被去掉主要是因为两种特殊的浏览器:PlayStation 3 浏览器不⽀持ferrer,Opera去掉
也有证据表明,Referer被去掉是由于涉及到隐私问题,当浏览器把Referer从⽹站A发送到⽹站B时,⽤户的隐私也在被暴露,因为⽹站B可以通过Referer来收集⽤户在⽹站A的浏览⾏为。相⽐之下,在同域下发送Referer则不会引起隐私问题,因为⽹站完全可以通过cookie来收集⽤户的隐私(也就是完全没有必要通过Referer来收集)。我们还发现,跨站请求⽐同站请求要更多的阻⽌Referer,说明由于考虑到
隐私的问题,所以才会⼈为的阻⽌Referer发送。
由此,我们得出两个主要的结论:
1、通过HTTPS来防御CSRF。在HTTPS请求⾥,Referer可以被⽤来防御CSRF。为了实施⽤Referer来防御CSRF的策略,⽹站必须拒绝那些没有Referer的请求,因为攻击者可以控制浏览器来去掉Referer。⽽在HTTP⾥,⽹站则不能⼀味的拒绝没有Referer的请求,因为考虑到兼容性,可能有相当⼤⼀部分 (⼤约 3–11%)⽤户可能就访问不了⽹站了。不同的是在HTTPS⾥,则可以执⾏严格的Referer验证策略,因为只有很⼩的⼀部分(0.05–0.22%)浏览器会去掉Referer。特别需要指出的是,严格的Referer验证策略⾮常适合⽤来防御登陆CSRF,因为通常情况下,登陆请求都是通过HTTPS协议发起的。
2、隐私问题。严格的Referer策略是很好的CSRF的防御⽅案,因为它实施起来很简单。不幸的是,隐私策略可能会阻⽌此⽅案的流⾏。因此,浏览器新的安全性能和新的CSRF防御机制都必须要先解决好隐私问题,才能⼤规模的部署。
图3. ⼴告渠道A中不包含Referer和Referer不正确的请求(241,483 个结果)。Opera阻⽌了跨站的ferrer,Firefox 1.0和1.5由于bug在XMLHttpRequest的时候不发送Referer,PlayStation 3(图中即为PS)不⽀持ferrer。
4.3 ⾃定义HTTP header
我们也可以⽤⾃定义HTTP头的⽅法来防御CSRF攻击,因为虽然浏览器会阻⽌向外站发送⾃定义的HTTP头,但是允许向本站通过XMLHttpRequest的⽅式发送⾃定义HTTP头。⽐如,prototype.js这个JavaScript库就是使⽤这种⽅法,并且增加了 X-Requested-By头到XMLHttpRequest⾥⾯。Google Web Toolkit 也建议开发者⽤在XMLHttpRequest⾥增加⼀个X-XSRF-Cookie头的⽅法来防御CSRF攻击,其中XMLHttpRequets包含有cookie的值。当然XMLHttpRequets⾥⾯的cookie并不需要⽤来防御CSRF,因为只需要有头部分就⾜够了。
在使⽤这种⽅法来防御CSRF攻击的时候,⽹站必须在所有的请求⾥使⽤XMLHttpRequest并附加⼀个⾃定义头(⽐如X-Requested-By),并且拒绝所有没有⾃定义头的的请求。例如,为了防御登陆CSRF的攻击,⽹站必须通过XMLHttpRequest的⽅式发送⽤户的⾝份验证信息到服务器。在我们的实验⾥,在服务器接收到的请求⾥⾯,⼤约有99.90–99.99%的请求是含有X-Requested-By头的,这表明这⼀⽅法适⽤于绝⼤多数的⽤户。
五、建议:Origin字段
为了防⽌CSRF的攻击,我们建议修改浏览器在发送POST请求的时候加上⼀个Origin字段,这个Origin字段主要是⽤来标识出最初请求是从哪⾥发起的。如果浏览器不能确定源在哪⾥,那么在发送的请求⾥⾯Origin字段的值就为空。
隐私⽅⾯:这种Origin字段的⽅式⽐Referer更⼈性化,因为它尊重了⽤户的隐私。
1、Origin字段⾥只包含是谁发起的请求,并没有其他信息 (通常情况下是⽅案,主机和活动⽂档URL的端⼝)。跟Referer不⼀样的是,Origin 字段并没有包含涉及到⽤户隐私的URL路径和请求内容,这个尤其重要。
2、Origin字段只存在于POST请求,⽽Referer则存在于所有类型的请求。
随便点击⼀个超链接(⽐如从搜索列表⾥或者企业intranet),并不会发送Origin字段,这样可以防⽌敏感信息的以外泄露。
在应对隐私问题⽅⾯,Origin字段的⽅法可能更能迎合⽤户的⼝味。
服务端要做的:⽤Origin字段的⽅法来防御CSRF攻击的时候,⽹站需要做到以下⼏点:
1、在所有能改变状态的请求⾥,包括登陆请求,都必须使⽤POST⽅法。对于⼀些特定的能改变状态的GET请求必须要拒绝,这是为了对抗上⽂中提到过的论坛张贴的那种危害类型。
2、对于那些有Origin字段但是值并不是我们希望的(包括值为空)请求,服务器要⼀律拒绝。⽐如,服务器可以拒绝⼀切Origin字段为外站的请求。
安全性分析:虽然Origin字段的设计⾮常简单,但是⽤它来防御CSRF攻击可以起到很好的作⽤。
1、去掉Origin字段。由于⽀持这种⽅法的浏览器在每次POST请求的时候都会带上源header,那么⽹站就可以通过查看是否存在这种Origin 字段来确定请求是否是由⽀持这种⽅法的浏览器发起的。这种设计能有效防⽌攻击者将⼀个⽀持这种⽅法的浏览器改变成不⽀持这种⽅法的浏览器,因为即使你改变浏览器去掉了Origin字段,Origin字段还是存在,只不过值变为空了。这跟Referer很不⼀样,因为Referer 只要是在请求⾥去掉了,那服务器就探测不到了。
2、DNS重新绑定。在现有的浏览器⾥⾯,对于同站的XMLHttpRequests,Origin字段可以被伪造。只依赖⽹络连接进⾏⾝份验证的⽹站应当使⽤在第2章⾥提到的DNS重新绑定的⽅法,⽐如验证header⾥的Host字段。在使⽤Origin字段来防御CSRF攻击的时候,也需要⽤到DNS重新绑定的⽅法,他们是相辅相成的。当然对于在第四章⾥提到的CSRF防御⽅法,也需要⽤到DNS重新绑定的⽅法。
3、插件。如果⽹站根据l准备接受⼀个跨站HTTP请求的时候,攻击者可以在请求⾥⽤Flash Player来设置Origin字段。在处
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论