在本节中,将解释什么是跨域资源共享(CORS),描述一些基于跨域资源共享攻击的常见示例,并讨论如何防范这些攻击。
什么是跨域资源共享(CORS)?
跨域资源共享(CORS)是一种浏览器机制,允许对位于给定域之外的资源进行受控访问。它扩展并增加了同源策略(SOP)的灵活性。
但是,如果网站的CORS策略配置和实施不当,它也可能引起跨域攻击。CORS不能防止跨域攻击例如CSRF。
什么是同源策略(SOP)?
同源策略是一种限制性的跨域规范,它限制了网站与源域之外的资源进行交互的能力。同源策略是多年前定义的,以应对潜在的恶意跨域交互,例如一个网站从另一个网站窃取死人数据。它通常允许域向其他域发出请求,但不允许访问响应。
同源策略是一种网络浏览器安全机制,旨在防止网站相互攻击。
同源策略限制一个源上的脚本访问来自另一个源的数据。源由URI协议、域和端口组成。
例如,下面的URL:
这个URL的协议是http、域是normal-website.com、端口号是80,下表显示了如果上述URL的内容尝试访问其他来源,将如何应用同源策略:
注意,最后条IE浏览器将允许访问,因为IE在应用同源策略时不考虑端口号。
为什么需要同源策略?
当浏览器从一个源向另一个源发送HTTP请求时,与另一个域相关的任何cookie(包括身份验证会话cookie)也作为请求的一部分发送。
这意味着响应将在用户会话中生成,并包含特定于用户的任何相关数据。如果没有同源策略,访问了恶意网站,它将能够读取来自Gmail的电子邮件、来自Facebook的私人消息等。
同源策略如何实施?
同源策略通常控制JavaScript代码对跨域加载内容的访问权限,但通常允许跨域加载页面资源。
例如,SOP允许通过<img>标记嵌入图像,通过<video>标记嵌入媒体,以及通过<script>标记包含JavaScript。但是,虽然这些外部资源可以由页面加载,但页面上的任何JavaScript都无法读取这些资源的内容。
同源策略有多种例外情况:
●一些对象是跨域可写但不可读的,例如来自iframe或新窗口的location对象或locatino.href属性。
●有些对象是跨域可读但不可写的,比如window对象的length属性(存储页面上正在使用的帧数)和closed属性。
●可以跨域调用某些函数。例如,可以调用函数关闭、模糊和聚焦新窗口。postMessage函数也可以在iframe和新窗口上调用,以便将消息从一个域发送到另一个域。
由于遗留要求,在处理cookie时,同源策略更加宽松,因此它们通常可以从站点的所有子域访问,即使每个子域在技术上是不同的来源,可以使用HttpOnly cookie标志来部分减轻这种风险。
可以使用document.domain放宽同源策略,此特殊属性允许放宽特定域的SOP,但前提是它是FQDN(完全限定域名)的一部分。
例如,可能有一个域marketing.example.com,并且我们想在example.com上阅读该域的内容。为此,两个域都需要将document.domain设置为example.com。然后SOP将允许两个域之间的访问,尽管它们的来源不同。过去可以将document.domain设置为com之类的TLD,这允许在同一TLD上的任何域之间进行访问,但现在的浏览器阻止了这种情况。
放宽同源策略
同源策略非常严格,因此已经设计了各种方法来规避这些限制。许多网站以需要完全跨域访问的方式与子域或第三方网站进行交互。使用跨域资源共享(CORS)可以控制放宽同源策略。
跨域资源共享协议使用一套HTTP标头,这些标头定义了受信任的Web来源和相关属性,例如是否允许经过身份验证的访问。浏览器允许根据这些标头指令访问对跨域请求的响应。
什么是Access-Control-Allow-Origin响应标头?
Access-Control-Allow-Origin标头包含在一个网站对来自另一网站的请求的响应中,并标识请求的允许来源。Web浏览器将Access-Control-Allow-Origin与请求网站的来源进行比较,如果它们匹配,则允许访问响应。
实现简单的跨域资源共享
跨域资源共享(CORS)规范规定了Web服务器和浏览器之间交换的标头内容,以限制源域之外的Web资源请求的来源。CORS规范标识了一组协议标头,其中Access-Control-Allow-Origin是最重要的,当网站请求跨域资源时,服务器会返回此标头,并由浏览器添加Origin标头。
例如,假设一个来源为normal-website.com的网站引发了以下跨域请求:
robust-website.com上的服务器返回以下响应:
浏览器将允许在normal-website.com上运行的代码访问响应,因为来源匹配。
Access-Control-Allow-Origin的规范允许许多个来源,或者值为null,或者为通配符*。
但是,没有浏览器支持多个来源和通配符*。
使用凭据处理跨域资源请求
跨域资源请求的默认行为是在没有凭据(如cookie和Authorization标头)的情况下传递请求。但是,跨域服务器可以通过将CORS Access-Control-Allow-Credentials标头设置为true来允许在将凭据传递给它时读取响应。现在,如果请求网站使用JavaScript声明它正在发送带有请求的cookie:
对请求的响应是:
然后浏览器将允许请求网站读取响应,因为Access-Control-Allow-Credentials响应标头设置为true。否则,浏览器将不允许访问响应。
使用通配符放宽CORS规范
标头Access-Control-Allow-Origin支持通配符,例如:
但要注意,不能在任何其他值中使用通配符,例如,以下标头无效:
幸运的是,从安全角度来看,通配符的使用在规范中受到限制,因为不能将通配符与凭据的跨域传输(身份验证、cookie或客户端证书)结合使用。
因此,以下形式的跨域服务器响应:
将会被禁止,因为这是非常危险的,将目标站点上的任何经过身份验证的内容暴露给所有人。
鉴于这些限制,一些Web服务器会根据客户端指定的来源动态创建Access-Control-Allow-Origin标头,这是不安全的CORS约束的解决方法。
飞行前检查
飞行前检查已经被添加到了CORS规范中,以保护遗留资源免受CORS允许的扩展请求选项的影响。
在某些情况下,当跨域请求包含非标准HTTP方法或标头时,跨域请求之前会出现使用OPTIONS方法的请求,并且CORS协议需要在允许跨域请求之前对允许的方法和标头进行初始检查,这就是飞行前检查。
除了受信任的来源之外,服务器还会返回允许的方法列表,并且浏览器会检查请求网站的方法是否被允许。
例如下面所示,这是一个飞行前检查,它试图将PUT方法与一个名为Special-Request-Header的自定义请求标头一起使用:
服务器可能会返回如下响应:
这个响应列出了允许的方法(PUT、POST和OPTIONS)和允许的请求标头(Special-Request-Header)。
在这种特殊的情况下,跨域服务器还允许发送凭据,并且Access-Control-Max-Age标头定义了用于缓存飞行前响应以供重用的最大时间范围。
如果允许请求方法和标头(如本例中所示),则浏览器以通常的方式处理跨域请求。
飞行前检查为跨域请求添加了额外的HTTP请求往返,因此它们会增加浏览器的开销。
CORS是否可以防止CSRF?
CORS不提供针对跨站点请求伪造(CSRF)攻击的保护,这是一种常见的误解。
CORS是对同源策略的一种受控放宽,因此配置不当的CORS实际上可能会增加CSRF攻击的可能性或加剧其影响。
有多种方法可以在不使用CORS的情况下执行CSRF攻击,包括简单的HTML表单和跨域资源包含。
如何防止基于CORS的攻击
CORS漏洞主要是由于配置而出现的,因此,如何预防是一个配置问题。
●正确配置跨域请求:如果Web资源包含敏感信息,则应在Access-Control-Allow-Origin标头中正确指定来源。
●只允许受信任的站点:Access-Control-Allow-Origin标头中指定的来源应该只是受信任的站点,特别是,未经验证的跨域请求动态反映来源很容易被利用,应该避免。
●避免将null列入白名单:避免使用标头Access-Control-Allow-Origin:null,来自内部文档和沙盒请求的跨域资源调用可以指定空源,应针对是有和公共服务器的可信来源正确定义CORS标头。
●避免在内部网络中使用通配符:当内部浏览器可以访问不受信任的外部域时,仅信任网络配置来保护内部资源是不够的。
●CORS不能替代服务器端安全策略:CORS定义了浏览器行为,并且永远不会替代敏感数据的服务器端保护。因此,除了正确配置CORS外,Web服务器还应继续对敏感数据应用保护,例如身份验证和会话管理。
SQL注入攻击-检索隐藏的数据
HTTP Host头漏洞攻击-概念梳理
原文始发于微信公众号(H君网安白话):跨域资源共享(CORS)-概念梳理
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论