转发 CSRF & CORS 的区别javascript
下面转的两篇文章分别说明了如下两个概念和一些解决方法:html
1. CSRF - Cross-Site Request Forgery - 跨站请求伪造java
2. CORS - Cross Origin Resourse-Sharing - 跨站资源共享程序员
(1. CSRF)转自:http://www.h3c.com.cn/About_H3C/Company_Publication/IP_Lh/2012/04/Home/Catalog/201208/751467_30008_0.htmweb
从下面文章中能够知道为何要设置csrf_token,以及为何一些网站把csrf_token放入header或url。ajax
CSRF(Cross-Site Request Forgery,跨站点伪造请求)是一种网络攻击方式,该攻击能够在受害者绝不知情的状况下以受害者名义伪造请求发送给受攻击站点,从而在未受权的状况下执行在权限保护之下的操做,具备很大的危害性。具体来说,能够这样理解CSRF攻击:攻击者盗用了你的身份,以你的名义发送恶意请求,对服务器来讲这个请求是彻底合法的,可是却完成了攻击者所指望的一个操做,好比以你的名义发送邮件、发消息,盗取你的帐号,添加系统管理员,甚至于购买商品、虚拟货币转帐等。shell
CSRF攻击方式并不为你们所熟知,实际上不少网站都存在CSRF的安全漏洞。早在2000年,CSRF这种攻击方式已经由国外的安全人员提出,但在国内,直到2006年才开始被关注。2008年,国内外多个大型社区和交互网站前后爆出CSRF漏洞,如:百度HI、NYTimes.com(纽约时报)、Metafilter(一个大型的BLOG网站)和YouTube等。但直到如今,互联网上的许多站点仍对此毫无防备,以致于安全业界称CSRF为“沉睡的巨人”,其威胁程度由此“美誉”即可见一斑。后端
CSRF攻击原理跨域
CSRF攻击原理比较简单,如图1所示。其中Web A为存在CSRF漏洞的网站,Web B为攻击者构建的恶意网站,User C为Web A网站的合法用户。浏览器
图1 CSRF攻击原理
1. 用户C打开浏览器,访问受信任网站A,输入用户名和密码请求登陆网站A;
2.在用户信息经过验证后,网站A产生Cookie信息并返回给浏览器,此时用户登陆网站A成功,能够正常发送请求到网站A;
3. 用户未退出网站A以前,在同一浏览器中,打开一个TAB页访问网站B;
4. 网站B接收到用户请求后,返回一些攻击性代码,并发出一个请求要求访问第三方站点A;
5. 浏览器在接收到这些攻击性代码后,根据网站B的请求,在用户不知情的状况下携带Cookie信息,向网站A发出请求。网站A并不知道该请求实际上是由B发起的,因此会根据用户C的Cookie信息以C的权限处理该请求,致使来自网站B的恶意代码被执行。
CSRF攻击分类
CSRF漏洞通常分为站外和站内两种类型。
CSRF站外类型的漏洞本质上就是传统意义上的外部提交数据问题。一般程序员会考虑给一些留言或者评论的表单加上水印以防止SPAM问题(这里,SPAM能够简单的理解为垃圾留言、垃圾评论,或者是带有站外连接的恶意回复),可是有时为了提升用户的体验性,可能没有对一些操做作任何限制,因此攻击者能够事先预测并设置请求的参数,在站外的Web页面里编写脚本伪造文件请求,或者和自动提交的表单一块儿使用来实现GET、POST请求,当用户在会话状态下点击连接访问站外Web页面,客户端就被强迫发起请求。
CSRF站内类型的漏洞在必定程度上是因为程序员滥用REQUEST类变量造成的。在一些敏感的操做中(如修改密码、添加用户等),本来要求用户从表单提交发起POST请求传递参数给程序,但是由于使用了REQUEST类变量形成的。在一些敏感的操做中(如修改密码、添加用户等),原本要求用户从表单提交发起POST请求传递参数给程序,可是因为使用了_REQUEST等变量,程序除支持接收POST请求传递的参数外也支持接收GET请求传递的参数,这样就会为攻击者使用CSRF攻击创造条件。通常攻击者只要把预测的请求参数放在站内一个贴子或者留言的图片连接里,受害者浏览了这样的页面就会被强迫发起这些请求。
CSRF攻击实例
下面以Axous 1.1.1 CSRF Add Admin Vulnerability(漏洞CVE编号:CVE-2012-2629)为例,介绍CSRF攻击具体实施过程。
Axous是一款网上商店应用软件。Axous 1.1.1以及更低版本在实现上存在一个CSRF漏洞,远程攻击者能够经过构造特制的网页,诱使该软件管理员访问,成功利用此漏洞的攻击者能够添加系统管理员。利用此漏洞主要包含如下三个过程:
1. 攻击者构造恶意网页。在实施攻击前,攻击者须要构造一个与正常添加管理员用户基本同样的网页,在该恶意网页中对必要的参数项进行赋值,并将该网页的action指向正常添加管理员用户时访问的URL,核心代码如图2所示;
2. 攻击者利用社会工程学诱使Axous系统管理员访问其构造的恶意网页;
3. 执行恶意代码。当系统管理员访问恶意网页时,恶意代码在管理员不知情的状况下以系统管理员的合法权限被执行,攻击者伪造的管理员帐户添加成功。
图2 CSRF攻击添加管理员核心代码
检测CSRF漏洞是一项比较繁琐的工做,最简单的方法就是抓取一个正常请求的数据包,去掉Referer字段后再从新提交,若是该提交还有效,那么基本上能够肯定存在CSRF漏洞。
随着对CSRF漏洞研究的不断深刻,不断涌现出一些专门针对CSRF漏洞进行检测的工具,如CSRFTester,CSRF Request Builder等。
以CSRFTester工具为例,CSRF漏洞检测工具的测试原理以下:使用CSRFTester进行测试时,首先须要抓取咱们在浏览器中访问过的全部连接以及全部的表单等信息,而后经过在CSRFTester中修改相应的表单等信息,从新提交,这至关于一次伪造客户端请求。若是修改后的测试请求成功被网站服务器接受,则说明存在CSRF漏洞,固然此款工具也能够被用来进行CSRF攻击。
CSRF漏洞防护主要能够从三个层面进行,即服务端的防护、用户端的防护和安全设备的防护。
目前业界服务器端防护CSRF攻击主要有三种策略:验证HTTP Referer字段,在请求地址中添加token并验证,在HTTP头中自定义属性并验证。下面分别对这三种策略进行简要介绍。
根据HTTP协议,在HTTP头中有一个字段叫Referer,它记录了该HTTP请求的来源地址。在一般状况下,访问一个安全受限页面的请求必须来自于同一个网站。好比某银行的转帐是经过用户访问http://bank.test/test?page=10&userID=101&money=10000页面完成,用户必须先登陆bank. test,而后经过点击页面上的按钮来触发转帐事件。当用户提交请求时,该转帐请求的Referer值就会是转帐按钮所在页面的URL(本例中,一般是以bank. test域名开头的地址)。而若是攻击者要对银行网站实施CSRF攻击,他只能在本身的网站构造请求,当用户经过攻击者的网站发送请求到银行时,该请求的Referer是指向攻击者的网站。所以,要防护CSRF攻击,银行网站只须要对于每个转帐请求验证其Referer值,若是是以bank. test开头的域名,则说明该请求是来自银行网站本身的请求,是合法的。若是Referer是其余网站的话,就有多是CSRF攻击,则拒绝该请求。
CSRF攻击之因此可以成功,是由于攻击者能够伪造用户的请求,该请求中全部的用户验证信息都存在于Cookie中,所以攻击者能够在不知道这些验证信息的状况下直接利用用户本身的Cookie来经过安全验证。由此可知,抵御CSRF攻击的关键在于:在请求中放入攻击者所不能伪造的信息,而且该信息不存在于Cookie之中。鉴于此,系统开发者能够在HTTP请求中以参数的形式加入一个随机产生的token,并在服务器端创建一个拦截器来验证这个token,若是请求中没有token或者token内容不正确,则认为多是CSRF攻击而拒绝该请求。
自定义属性的方法也是使用token并进行验证,和前一种方法不一样的是,这里并非把token以参数的形式置于HTTP请求之中,而是把它放到HTTP头中自定义的属性里。经过XMLHttpRequest这个类,能够一次性给全部该类请求加上csrftoken这个HTTP头属性,并把token值放入其中。这样解决了前一种方法在请求中加入token的不便,同时,经过这个类请求的地址不会被记录到浏览器的地址栏,也不用担忧token会经过Referer泄露到其余网站。
对于普通用户来讲,都学习并具有网络安全知识以防护网络攻击是不现实的。但若用户养成良好的上网习惯,则可以很大程度上减小CSRF攻击的危害。例如,用户上网时,不要轻易点击网络论坛、聊天室、即时通信工具或电子邮件中出现的连接或者图片;及时退出长时间不使用的已登陆帐户,尤为是系统管理员,应尽可能在登出系统的状况下点击未知连接和图片。除此以外,用户还须要在链接互联网的计算机上安装合适的安全防御软件,并及时更新软件厂商发布的特征库,以保持安全软件对最新攻击的实时跟踪。
(转自http://netsecurity.51cto.com/art/201311/419179.htm)
1、背景
提起浏览器的同源策略,你们都很熟悉。不一样域的客户端脚本不能读写对方的资源。可是实践中有一些场景须要跨域的读写,因此出现了一些hack的方式来跨域。好比在同域内作一个代理,JSON-P等。但这些方式都存在缺陷,没法完美的实现跨域读写。因此在XMLHttpRequest v2标准下,提出了CORS(Cross Origin Resourse-Sharing)的模型,试图提供安全方便的跨域读写资源。目前主流浏览器均支持CORS。
2、技术原理
CORS定义了两种跨域请求,简单跨域请求和非简单跨域请求。当一个跨域请求发送简单跨域请求包括:请求方法为HEAD,GET,POST;请求头只有4个字段,Accept,Accept-Language,Content-Language,Last-Event-ID;若是设置了Content-Type,则其值只能是application/x-www-form-urlencoded,multipart/form-data,text/plain。提及来比较别扭,简单的意思就是设置了一个白名单,符合这个条件的才是简单请求。其余不符合的都是非简单请求。
之因此有这个分类是由于浏览器对简单请求和非简单请求的处理机制是不同的。当咱们须要发送一个跨域请求的时候,浏览器会首先检查这个请求,若是它符合上面所述的简单跨域请求,浏览器就会马上发送这个请求。若是浏览器检查以后发现这是一个非简单请求,好比请求头含有X-Forwarded-For字段。这时候浏览器不会立刻发送这个请求,而是有一个preflight,跟服务器验证的过程。浏览器先发送一个options方法的预检请求。下图是一个示例。若是预检经过,则发送这个请求,不然就不拒绝发送这个跨域请求。
下面详细分析一下实现安全跨域请求的控制方式。先看一下非简单请求的预检过程。浏览器先发送一个options方法的请求。带有以下字段:
Origin: 普通的HTTP请求也会带有,在CORS中专门做为Origin信息供后端比对,代表来源域。
Access-Control-Request-Method: 接下来请求的方法,例如PUT, DELETE等等
Access-Control-Request-Headers: 自定义的头部,全部用setRequestHeader方法设置的头部都将会以逗号隔开的形式包含在这个头中
而后若是服务器配置了cors,会返回对应对的字段,具体字段含义在返回结果是一并解释。
Access-Control-Allow-Origin:
Access-Control-Allow-Methods:
Access-Control-Allow-Headers:
而后浏览器再根据服务器的返回值判断是否发送非简单请求。简单请求前面讲过是直接发送,只是多加一个origin字段代表跨域请求的来源。而后服务器处理完请求以后,会再返回结果中加上以下控制字段:
Access-Control-Allow-Origin: 容许跨域访问的域,能够是一个域的列表,也能够是通配符"*"。这里要注意Origin规则只对域名有效,并不会对子目录有效。即http://foo.example/subdir/ 是无效的。可是不一样子域名须要分开设置,这里的规则能够参照同源策略
Access-Control-Allow-Credentials: 是否容许请求带有验证信息,这部分将会在下面详细解释
Access-Control-Expose-Headers: 容许脚本访问的返回头,请求成功后,脚本能够在XMLHttpRequest中访问这些头的信息(貌似webkit没有实现这个)
Access-Control-Max-Age: 缓存这次请求的秒数。在这个时间范围内,全部同类型的请求都将再也不发送预检请求而是直接使用这次返回的头做为判断依据,很是有用,大幅优化请求次数
Access-Control-Allow-Methods: 容许使用的请求方法,以逗号隔开
Access-Control-Allow-Headers: 容许自定义的头部,以逗号隔开,大小写不敏感
而后浏览器经过返回结果的这些控制字段来决定是将结果开放给客户端脚本读取仍是屏蔽掉。若是服务器没有配置cors,返回结果没有控制字段,浏览器会屏蔽脚本对返回信息的读取。
3、安全隐患
你们注意这个流程。服务器接收到跨域请求的时候,并无先验证,而是先处理了请求。因此从某种程度上来讲。在支持cors的浏览器上实现跨域的写资源,打破了传统同源策略下不能跨域读写资源。
再一个就是若是程序猿偷懒将Access-Control-Allow-Origin设置为容许来自全部域的跨域请求。那么cors的安全机制几乎就无效了。不过先别高兴的太早。其实这里在设计的时候有一个很好的限制。xmlhttprequest发送的请求须要使用“withCredentials”来带上cookie,若是一个目标域设置成了容许任意域的跨域请求,这个请求又带着cookie的话,这个请求是不合法的。(就是若是须要实现带cookie的跨域请求,须要明确的配置容许来源的域,使用任意域的配置是不合法的)浏览器会屏蔽掉返回的结果。javascript就无法获取返回的数据了。这是cors模型最后一道防线。假如没有这个限制的话,那么javascript就能够获取返回数据中的csrf token,以及各类敏感数据。这个限制极大的下降了cors的风险。
4、攻击模型
从思路上讲,有两种类型的攻击方式。一种是在攻击者本身控制的网页上嵌入跨域请求,用户访问连接,执行了跨域请求,从而攻击目标,好比访问了内网敏感资源。还有一种是正常的网页被嵌入了到攻击者控制页面的跨域请求,从而劫持用户的会话。
5、攻击场景
先看第一种思路的攻击场景:
1,复杂csrf。传统的csrf都是利用html标签和表单来发送请求。没有办法实现一些复杂步骤的csrf,好比模拟购物,先加购物车,结算,填写信息,等等。好比上传文件。具体能够参考利用csrf上传文件
2,访问内网敏感资源。这个在必定的条件下是能够实现的。好比内网的服务器配置了
Access-Control-Allow-Origin: * 容许任何来自任意域的跨域请求
用户访问恶意网页的时候,执行了到内网服务器192.168.1.123/password.txt的请求,脚本在接收到服务器返回以后,将内容发送到攻击者的服务器上。
第二种思路的场景:
1,交互式xss。参考揭密HTML5带来的攻击手法中讲到的shell of the future工具。经过cors,绕过一些反会话劫持的方法,如HTTP-Only限制的cookie,绑定IP地址的会话ID等,劫持用户会话。
2,程序猿在写ajax请求的时候,对目标域限制不严。有点相似于url跳转。facebook出现过这样一个案例。javascript经过url里的参数进行ajax请求。经过控制这个参数实现注入攻击。