跨域资源共享(CORS)

一、背景

提起浏览器的同源策略,大家都很熟悉。不同域的客户端脚本不能读写对方的资源。但是实践中有一些场景需要跨域的读写,所以出现了一些hack的方式来跨域。比如在同域内做一个代理,JSON-P等。但这些方式都存在缺陷,无法完美的实现跨域读写。所以在XMLHttpRequest v2标准下,提出了CORS(Cross Origin Resourse-Sharing)的模型,试图提供安全方便的跨域读写资源。目前主流浏览器均支持CORS。

二、技术原理

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,返回结果没有控制字段,浏览器会屏蔽脚本对返回信息的读取。

三、安全隐患

大家注意这个流程。服务器接收到跨域请求的时候,并没有先验证,而是先处理了请求。所以从某种程度上来说。在支持cors的浏览器上实现跨域的写资源,打破了传统同源策略下不能跨域读写资源。

再一个就是如果程序猿偷懒将Access-Control-Allow-Origin设置为允许来自所有域的跨域请求。那么cors的安全机制几乎就无效了。不过先别高兴的太早。其实这里在设计的时候有一个很好的限制。xmlhttprequest发送的请求需要使用“withCredentials”来带上cookie,如果一个目标域设置成了允许任意域的跨域请求,这个请求又带着cookie的话,这个请求是不合法的。(就是如果需要实现带cookie的跨域请求,需要明确的配置允许来源的域,使用任意域的配置是不合法的)浏览器会屏蔽掉返回的结果。javascript就没法获取返回的数据了。这是cors模型最后一道防线。假如没有这个限制的话,那么javascript就可以获取返回数据中的csrf token,以及各种敏感数据。这个限制极大的降低了cors的风险。

四、攻击模型

从思路上讲,有两种类型的攻击方式。一种是在攻击者自己控制的网页上嵌入跨域请求,用户访问链接,执行了跨域请求,从而攻击目标,比如访问了内网敏感资源。还有一种是正常的网页被嵌入了到攻击者控制页面的跨域请求,从而劫持用户的会话。

五、攻击场景

先看第一种思路的攻击场景:

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请求。通过控制这个参数实现注入攻击。

致谢

本文参考了nyannyannyangerionsecurity.com的文章,表示感谢。

转载:http://netsecurity.51cto.com/art/201311/419179.htm

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,716评论 4 364
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,558评论 1 294
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 109,431评论 0 244
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,127评论 0 209
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,511评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,692评论 1 222
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,915评论 2 313
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,664评论 0 202
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,412评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,616评论 2 245
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,105评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,424评论 2 254
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,098评论 3 238
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,096评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,869评论 0 197
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,748评论 2 276
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,641评论 2 271

推荐阅读更多精彩内容