设置访问控制允许来源有哪些安全隐患?


124

我最近不得不设置Access-Control-Allow-Origin*,以便能够进行跨子域的ajax调用。
现在,我不禁感到自己正在使环境面临安全风险。
如果我做错了,请帮助我。

Answers:


69

通过使用响应Access-Control-Allow-Origin: *,所请求的资源允许与每个来源共享。基本上,这意味着任何站点都可以向您的站点发送XHR请求并访问服务器的响应,如果您尚未实现此CORS响应,则不会这样。

因此,任何站点都可以代表其访问者向您的站点发出请求并处理其响应。如果您基于浏览器自动提供的内容(例如cookie,基于cookie的会话等)实施了诸如身份验证或授权方案之类的内容,则由第三方站点触发的请求也将使用它们。

这确实带来了安全风险,特别是如果您不仅允许共享选定资源,还允许共享每个资源的资源,则尤其如此。在这种情况下,您应该看看什么时候可以启用CORS?


2
如果您能给出共享认证访问如何构成安全风险的特定示例,我将对此表示赞同。
Petrus Theron 2013年

1
@Gumbo静态内容呢?(例如,静态CDN内容,例如javascript,css,静态html等)。在设置Access-Control-Allow-Origin: *这些内容时是否存在安全问题?不会有Nogin等,它们对所有人都公开吗?
Umut Benzer

2
@UmutBenzer没关系。
Gumbo

25
实际上,根据当前的CORS标准,此答案不太正确:“字符串'*'不能用于支持凭据的资源。” 因此,您不能强制请求以Cookie,缓存的HTTP身份验证或客户端SSL证书的形式使用临时身份验证。但是,如果该网站要使用本地存储进行身份验证,那将是一个问题。
Niklas B.

2
@NiklasB:我尝试了这种情况,Chrome确实遵循了您提到的CORS标准。即,凭据请求不支持字符串“ ”。这是Chrome报告的内容:“ XMLHttpRequest无法加载localhost:12346 / hello当凭据标记为true时,不能在'Access-Control-Allow-Origin'标头中使用通配符' '。起源' localhost:12345 '因此,不允许访问。XMLHttpRequest的凭据模式由withCredentials属性控制。”
factotum

37

Access-Control-Allow-Origin: *完全安全地添加到任何资源,除非该资源包含受非标准凭据(Cookie,基本身份验证,TLS客户端证书)以外的内容保护的私有数据。

例如:受Cookie保护的数据是安全的

想象一下https://example.com/users-private-data,它可能会公开私有数据,具体取决于用户的登录状态。此状态使用会话cookie。添加到该资源是安全的Access-Control-Allow-Origin: *,因为只有在没有cookie的情况下发出请求,并且需要cookie才能获取私有数据时,此标头才允许访问响应。结果,没有私有数据泄漏。

例如:受位置/ ip /内部网络保护的数据并不安全(不幸的是,内部网和家用电器很常见):

想象一下https://intranet.example.com/company-private-data,它公开了私人公司的数据,但是只有在公司的wifi网络上,才能访问该数据。这是不是安全添加Access-Control-Allow-Origin: *到这个资源,因为它使用比标准凭据以外的东西保护。否则,错误的脚本可能会将您用作通往Intranet的隧道。

经验法则

想象一下,如果用户在隐身窗口中访问资源,将会看到什么。如果您对所有人都能看到此内容(包括浏览器收到的源代码)感到满意,则可以安全地添加Access-Control-Allow-Origin: *


应该“因为它只允许不带cookie的请求”应该是“因为它只允许不带cookie的请求”吗?
DJCordhose

3
@DJCordhose号 Access-Control-Allow-Origin: *仅允许没有 Cookie的请求。我已经对答案进行了编辑以弄清楚。
JaffaTheCake

“ *”和完全没有此标头的大小写有什么区别。一样吗
Nigrimmist

如果“否则,错误的脚本可能会将您用作通往Intranet的隧道”,我将很乐意进一步解释。
山姆·鲁比(19.10.09)

@Nigrimmist然后,预检请求将失败并且资源访问将被阻止
iamareebjamal

9

AFAIK,Access-Control-Allow-Origin只是从服务器发送到浏览器的http标头。将其限制为一个特定的地址(或禁用它)不会使您的网站更安全,例如,机器人。如果机器人愿意,他们可以忽略标题。默认情况下,常规浏览器(Explorer,Chrome等)使用标头。但是像Postman这样的应用程序只会忽略它。

当服务器端返回响应时,它实际上并不检查请求的“来源”是什么。它只是添加http标头。发送请求的是浏览器(客户端),它决定读取访问控制标头并对其执行操作。请注意,在XHR的情况下,它可以使用特殊的“ OPTIONS”请求首先请求标头。

因此,具有创意脚本功能的任何人都可以轻松忽略整个标头,无论其中设置了什么。

另请参阅设置Access-Control-Allow-Origin的可能的安全问题


现在要实际回答问题

我忍不住觉得自己正在使我的环境面临安全风险。

如果有人想攻击您,他们可以轻松绕过Access-Control-Allow-Origin。但是通过启用“ *”,您确实可以给攻击者更多的“攻击向量”,例如,使用支持该HTTP标头的常规网络浏览器。


6
从一个粗心的最终用户的角度来看这个问题。有人可以设置一个恶意网页,该网页注入JavaScript以在真实站点和恶意站点之间传递数据(假设他们想窃取您的密码)。最终用户的Web浏览器通常会阻止此跨站点通信,但是如果设置了Access-Control-Allow-Origin,则将允许它,而最终用户将是一个明智的选择。
Brain2000 2014年

3
是的,Access-Control-Allow-Origin *强烈建议不要在托管脚本的恶意网站上进行设置以窃取密码:-)
commonpike 2014年

6
@commonpike您是对的,因为有人可以编写脚本以完全忽略标头。如果数据是可访问的,则可以使用或不使用CORS标头进行访问。不过,您没有考虑另一个攻击媒介。假设我登录了银行的网站。如果我转到另一个页面,然后再返回我的银行,则由于cookie的缘故,我仍然登录。互联网上的其他用户可以在我的银行中访问与我相同的URL,但是如果没有Cookie,他们将无法访问我的帐户。如果跨域请求被允许,则恶意网站可以有效假冒...
Brad

5
@commonpike ...用户。换句话说,您可能只是访问我的网站(甚至可能是一个普通网站,没有任何可疑...也许这是一个真正的合法网站,被劫持了!),但是有些JavaScript向您的银行发出HTTP请求以转移一些资金到我的帐户。银行不知道其页面请求与其他页面请求之间的区别。两者都有该cookie,以使请求成功。
布拉德(Brad)

3
@commonpike让我给你一个更常见的例子...一个无时无刻不在发生的例子。假设您有一个普通的家用路由器,例如Linksys WRT54g等。假设路由器允许跨域请求。我网页上的脚本可以向常见的路由器IP地址(例如192.168.1.1)发出HTTP请求,并重新配置路由器以允许攻击。它甚至可以将您的路由器直接用作DDoS节点。(大多数路由器的测试页都允许ping或简单的HTTP服务器检查。这些测试页可能会被大量滥用。)
Brad

7

当通配符确实有问题时,这里有两个示例以注释形式发布:

假设我登录了银行的网站。如果我转到另一个页面,然后再返回银行,则由于cookie的缘故,我仍然登录。互联网上的其他用户可以在我的银行中访问与我相同的URL,但是如果没有Cookie,他们将无法访问我的帐户。如果允许跨域请求,则恶意网站可以有效地冒充用户。

布拉德

假设您有一个普通的家用路由器,例如Linksys WRT54g等。假设路由器允许跨域请求。我网页上的脚本可以向公用路由器IP地址(例如192.168.1.1)发出HTTP请求,并重新配置路由器以允许攻击。它甚至可以将您的路由器直接用作DDoS节点。(大多数路由器的测试页均允许ping或简单的HTTP服务器检查。这些测试页可能会被大量滥用。)

布拉德

我认为这些评论应该是答案,因为它们以一个真实的例子来解释问题。


8
除非这行不通。“字符串'*'不能用于支持凭据的资源。” w3.org/TR/cors/#resource-requests
bayo's

@bayotop浏览器如何区分需要身份验证的页面和标头中包含其他数据的页面?
wedstrom

阅读提供的链接后,将有一个“支持凭证标志”用于此目的。它似乎是手动设置的,因此大概是如果有人不知道如何正确设置CORS的话,他们也可能会弄错该标志,因此我相信上述漏洞是可能的。
wedstrom '17

2
@wedstrom该标志由发出请求的人设置。无论如何,以上情况都是CSRF攻击的示例。允许使用'*'来源不会使您更容易受到攻击(在极少数情况下可能会有点)。在大多数情况下,您可以使用表格提出恶意的跨站点请求,因此CORS无关紧要。如果您需要发出AJAX请求,则会进行预检请求(这是ACAO:“ *”和Access-Control-Allow-Credentials:“ true”时浏览器进入的点)。
bayo
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.