160

我最近不得不设置Access-Control-Allow-Origin*能够进行跨子域 AJAX 调用。我觉得这可能是一个安全问题。如果我保留该设置,我将面临哪些风险?

4

6 回答 6

88

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

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

这确实会带来安全风险,特别是如果您不仅允许选定资源共享资源,而且允许每个资源共享资源时。在这种情况下,您应该看看何时启用 CORS 是安全的?.

更新 (2020-10-07)

Current Fetch Standard在凭据模式设置为 时忽略凭据include,如果Access-Control-Allow-Origin设置为*

因此,如果您使用基于 cookie 的身份验证,则不会在请求中发送您的凭据。

于 2012-08-17T23:54:12.533 回答
60

Access-Control-Allow-Origin: *添加到任何资源是完全安全的,除非该资源包含受标准凭据以外的东西保护的私有数据。标准凭据是 cookie、HTTP 基本身份验证和 TLS 客户端证书。

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

想象一下https://example.com/users-private-data,这可能会根据用户的登录状态暴露私人数据。此状态使用会话 cookie。添加到此资源是安全Access-Control-Allow-Origin: *的,因为此标头仅在没有 cookie 的情况下允许访问响应,并且需要 cookie 才能获取私有数据。结果,没有私人数据被泄露。

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

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

经验法则

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

于 2019-06-05T09:22:27.620 回答
13

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

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

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

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


现在来实际回答这个问题

我不禁觉得我将我的环境置于安全风险之中。

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

于 2013-10-16T23:13:29.047 回答
11

以下是作为评论发布的 2 个示例,当通配符确实有问题时:

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

布拉德

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

布拉德

我觉得这些评论应该是答案,因为它们用现实生活中的例子解释了问题。

于 2017-03-26T12:20:08.477 回答
3

这个答案最初是作为对这个问题的回复而写的,What are the security implications of setting Access-Control-Allow-Headers: *, if any?尽管与这个问题无关,但还是被合并了。


将其设置为通配符*,意味着允许除安全列表之外所有标头,并删除确保它们安全的限制。

这些是被认为是安全的 4 个安全列表标头的限制:

  • 对于 Accept-Language 和 Content-Language:只能具有由0-9A-Za-z、 空格或组成的值*,-.;=
  • 对于 Accept 和 Content-Type: 不能包含 CORS 不安全的请求标头字节:(0x00-0x1F除了0x09(HT),这是允许的)"():<>?@[\]{}、 和0x7F(DEL)。
  • 对于 Content-Type:需要具有其解析值(忽略参数)的 MIME 类型,即application/x-www-form-urlencodedmultipart/form-datatext/plain
  • 对于任何标头:值的长度不能大于 128。

为简单起见,我将根据这些标题来回答。

根据服务器实现,简单地删除这些限制可能非常危险(对用户而言)。
例如,这个过时的 wordpress 插件有一个反射型 XSS 漏洞,其中的值Accept-Language被解析并按原样呈现在页面上,如果值中包含恶意负载,则会导致用户浏览器上的脚本执行。

使用通配符 header Access-Control-Allow-Headers: *,重定向到您网站的第三方站点可以将 header 的值设置为Accept Language: <script src="https://example.com/malicious-script.js"></script>,因为通配符删除了上面第 1 点中的限制。

然后,预检响应会对此请求开绿灯,并且用户将被重定向到您的站点,从而在他们的浏览器上触发 XSS,其影响范围可能从烦人的弹出窗口到通过 cookie 劫持失去对其帐户的控制。

因此,我强烈建议不要设置通配符,除非它用于在页面上没有呈现任何内容的 API 端点。

您可以设置Access-Control-Allow-Headers: Pragma为您的问题的替代解决方案。


请注意,*对于没有凭据的请求(没有 HTTP cookie 或 HTTP 身份验证信息的请求),该值仅计为特殊的通配符值,否则它将被读取为文字标头。文档

于 2021-09-23T17:45:44.790 回答
1

在服务器尝试通过设置以下标头来完全禁用 CORS 的情况下。

  • Access-Control-Allow-Origin:*(告诉浏览器服务器接受来自任何 ORIGIN 的跨站点请求)

  • Access-Control-Allow-Credentials: true(告诉浏览器跨站请求可以发送cookies)

在浏览器中实现了故障保护,这将导致以下错误

"Credential is not supported if the CORS header ‘Access-Control-Allow-Origin’ is ‘*’&quot;

因此,在大多数情况下,将“Access-Control-Allow-Origin”设置为*不会有问题。然而,为了防止攻击,服务器可以维护一个允许的来源列表,并且每当服务器收到一个跨来源请求时,它可以根据允许的来源列表验证 ORIGIN 标头,然后在 Access-Control-Allow-Origin 中回显相同的内容标题。

由于浏览器上运行的 javascript 无法更改 ORIGIN 标头,因此恶意站点将无法对其进行欺骗。

于 2020-08-03T07:22:31.340 回答