设置Access-Control-Allow-Origin有哪些安全隐患?

Ham*_*eni 108 security ajax cors

我最近不得不设置Access-Control-Allow-Origin*能够进行跨子域ajax调用.
现在我不禁觉得我的环境存在安全风险.
如果我做错了,请帮助我.

Gum*_*mbo 58

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

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

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

  • 实际上,根据[当前的CORS标准](http://www.w3.org/TR/cors/#resource-requests),这个答案并不完全正确:"字符串'*'不能用于支持的资源证书." 因此,您无法强制请求以cookie,缓存HTTP身份验证或客户端SSL证书的形式使用临时身份验证.但是,如果网站例如使用本地存储进行身份验证,那将是一个问题. (23认同)
  • 如果你能给出一个关于共享身份验证访问如何构成安全风险的具体示例,我将提出这个问题. (2认同)
  • @UmutBenzer没关系. (2认同)
  • @NiklasB:我尝试过这种情况,Chrome确实遵循了你提到的CORS标准.即凭证请求不支持字符串"*".以下是Chrome报告的内容:"XMLHttpRequest无法加载http:// localhost:12346/hello.当凭证标志为true时,不能在'Access-Control-Allow-Origin'标头中使用通配符'*'.因此,不允许'http:// localhost:12345'访问.XMLHttpRequest的凭证模式由withCredentials属性控制." (2认同)
  • 这绝对是一个安全风险 http://blog.portswigger.net/2016/10/exploiting-cors-misconfigurations-for.html 和 https://www.youtube.com/watch?v=wgkj4ZgxI4c (2认同)

Jaf*_*ake 30

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: *

  • @DJCordhose号 `Access-Control-Allow-Origin:*`只允许请求,而没有cookie。我已经对答案进行了编辑,以澄清一些问题。 (3认同)
  • @SamRueby 说你去了我的邪恶页面,我可以调用 fetch('https://intranet.example.com/company-private-data')`,它在你的机器上运行,并将结果发送回我的服务器。通过这样做,我已经使用了您对 Intranet 的访问权限来读取 Intranet。 (3认同)

com*_*ike 8

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

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

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

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


现在实际回答这个问题

我不禁觉得我的环境存在安全风险.

如果有人想要攻击你,他们可以轻松绕过Access-Control-Allow-Origin.但是通过启用"*",您可以为攻击者提供更多"攻击媒介",例如,使用支持HTTP标头的常规网络浏览器.

  • 从一个粗心的最终用户的角度来看这个.有人可以设置一个恶意网页,注入JavaScript以在真实网站和恶意网站之间传递数据(假设他们想要窃取您的密码).最终用户的Web浏览器通常会阻止此跨站点通信,但是如果设置了Access-Control-Allow-Origin,那么将允许它,并且最终用户将更加明智. (6认同)
  • @commonpike你是对的,因为有人可以制作一个完全忽略标题的脚本.如果数据可访问,则可以使用或不使用CORS头进行访问.还有另一个攻击向量,你不会考虑.假设我登录了我银行的网站.如果我去另一个页面然后回到我的银行,我仍然因为cookie而登录.互联网上的其他用户可以像我一样在我的银行点击相同的URL,但如果没有cookie,他们将无法访问我的帐户.如果允许跨域请求,恶意网站可以有效地冒充...... (6认同)
  • @commonpike ...用户.换句话说,你可能只是访问我的网站(甚至可能是一个普通的网站,没有任何可疑的......也许这是一个真正合法的网站,只是被劫持!)但是有些JavaScript会向你的银行发送HTTP请求转移一些资金到我的帐户.银行不知道来自其页面的请求或来自其他页面的请求之间的差异.两者都有cookie使请求成功. (5认同)
  • 是的,强烈建议不要在托管脚本来窃取密码的恶意网站上设置`Access-Control-Allow-Origin*`:-) (3认同)
  • @commonpike让我给你一个更常见的例子......一直在发生.假设您有一个普通的家用路由器,例如Linksys WRT54g或其他东西.假设路由器允许跨源请求.我的网页上的脚本可以向公共路由器IP地址(如"192.168.1.1")发出HTTP请求,并重新配置路由器以允许攻击.它甚至可以直接将您的路由器用作DDoS节点.(大多数路由器都有测试页面,允许ping或简单的HTTP服务器检查.这些可能会被滥用.) (3认同)
  • 哦,我为这个笑话做了一个downvote.不,我不能从用户的角度来看待它.网站管理员或网站建设者决定设置HTTP标头."有人可以设置恶意网页" - 是的,有人也会添加恶意指令.而且,任何客户端(如受感染的Web浏览器)都可以选择忽略其中设置的http标头. (2认同)
  • @commonpike通过不允许跨源请求,您可以有效地在两个不同站点可以从同一浏览器访问之间建立隔离墙.它可以防止一个站点访问另一个站点的数据,模拟可能以前登录过的用户. (2认同)
  • 这是一个没有答案的问题。Op 询问对所有域启用 CORS 的安全影响是什么。这个答案没有提供任何内容。 (2认同)

Chr*_*rdt 5

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

假设我登录了我银行的网站.如果我去另一个页面然后回到我的银行,我仍然因为cookie而登录.互联网上的其他用户可以像我一样在我的银行点击相同的URL,但如果没有cookie,他们将无法访问我的帐户.如果允许跨源请求,则恶意网站可以有效地冒充用户.

- 布拉德

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

- 布拉德

我觉得这些评论应该是答案,因为他们用reallife例子解释了这个问题.

  • 除此之外不起作用."字符串'*'不能用于支持凭据的资源." https://www.w3.org/TR/cors/#resource-requests (7认同)
  • @wedstrom标志由发出请求的人设置。无论如何,以上情况都是CSRF攻击的示例。允许'\ *'来源不会使您更容易受到攻击(在极少数情况下可能会稍有一些)。在大多数情况下,您可以使用表格提出恶意的跨站点请求,因此CORS无关紧要。如果您需要进行AJAX请求,则会进行预检请求(这是ACAO:'\ *'和Access-Control-Allow-Credentials:'true'时浏览器进入的地方) 。 (2认同)