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要求。经由过程节制这个参数实现注进报复打击。
称谢