将所有域添加到CORS的安全隐患(Access-Control-Allow-Origin:*)

bri*_*out 36 javascript security html5 denial-of-service cors

据说,不应该将所有域添加到CORS,而应该只添加一组域.然而,添加一组域有时并非易事.例如,如果我想公开公开API,那么对于想要调用该API的每个域,我需要联系以将该域添加到允许的域列表中.

我想在安全影响和减少工作之间做出有意识的权衡决定.

我看到的唯一安全问题是DoS攻击CSRF攻击.使用IMG元素和FORM元素已经可以实现CSRF攻击.可以通过阻止对引用者头部的请求来克服与CORS相关的DoS攻击.

我错过了安全隐患吗?


===编辑===

  • 假设Access-Control-Allow-Credentials未设置标头
  • 我知道如何添加一个给定的域"CORS访问"列表,因此我只对添加所有域"CORS访问"的安全隐患感兴趣

Jak*_*sel 27

跨站点请求伪造攻击是Access-Control-Allow-Origin解决的主要问题.

Ryan在内容检索方面肯定是正确的.但是,就提出要求的问题而言,还有更多要说的.许多网站现在提供RESTful Web服务,这些服务暴露了可能涉及在后端进行重大更改的各种功能.通常,这些RESTful服务旨在通过XHR(例如AJAX)请求(可能以" 单页应用程序 "作为前端)来调用.如果用户在访问恶意第三方站点时有活动会话授予对这些服务的访问权限,则该站点可能会尝试在后台调用这些REST端点,传入可能危及用户或站点的值.根据REST服务的定义方式,有多种方法可以防止这种情况发生.

在针对单页面应用程序的REST Web服务的特定情况下,您可以规定对后端REST端点的所有请求都是使用XHR进行的,并拒绝任何非XHR请求.您可以通过检查是否存在自定义请求标头(类似于jQuery的X-Requested-With)来指示这一点.只有XHR类型的请求可以设置这些标头; 表单和嵌入式资源的简单GET和POST请求不能.最后,我们想要指示XHR请求的原因让我们回到最初的问题 - XHR请求受CORS规则的约束.

如果您允许Access-Control-Allow-Origin: *,那么任何站点都可以代表用户向您的REST端点发出任何AJAX请求.如果您的REST端点涉及任何类型的敏感数据或允许数据持久性,那么这是一个不可接受的安全漏洞.相反,执行像我描述的仅XHR请求,并定义允许发出这些请求的原始白名单.

值得指出的是,如果您的REST端点没有暴露任何敏感信息,或者如果它们不允许用户进行任何持久性数据更改,那么Access-Control-Allow-Origin: *可能是适当的决定.例如,Google地图提供了对公共地图数据的只读视图; 没有理由限制可能希望调用这些服务的第三方站点.

  • 您的观点假设Cookie与请求一起发送,默认情况下不是这种情况.要发送Cookies,需要将另一个标题``Access-Control-Allow-Credentials``设置为``true`` (8认同)
  • Nowdays``localStorage``通常用于存储会话密钥,该会话密钥作为POST/GET参数在每个请求中发送.因此不需要Cookies,因此不需要设置"Access-Control-Allow-Credentials".正如我对我的问题的编辑所指定的那样,``Access-Control-Allow-Credentials``实际上没有设置.因此,不会发送任何Cookie. (8认同)
  • 我现在不知道你在说什么.如果您需要为特定用户进行任何类型的经过身份验证的会话,则需要某种持久性标识符才能传输到服务器.最典型的是cookie的形式,它也可以作为URL参数或自定义标题来完成.但无论如何,localStorage根本不会被发送到服务器,并且只能用于设置它的域.所以,我不明白你在这个问题的背景下做了什么. (3认同)
  • 如果您没有设置`Access-Control-Allow-Credentials`,并且您进行无cookie身份验证(即呼叫者提供Bearer Authorization标头),那么您不需要将域列入白名单.可以从任何来源调用结构良好的REST API. (3认同)
  • 如果使用``localStorage``,则不需要任何cookie (2认同)

csa*_*uve 12

老问题,但这里有很多不好的答案,所以我要添加我的.

如果您未设置Access-Control-Allow-Credentials,并且您执行无cookie身份验证(即呼叫者提供承载授权标头),则您不需要将起源列入白名单.只是回复原点Access-Control-Allow-Origin.

可以从任何来源安全地调用结构良好的REST API.


Hal*_*yon 9

您可以发送多个,例如:

Access-Control-Allow-Origin: http://my.domain.com https://my.domain.com http://my.otherdomain.com
Run Code Online (Sandbox Code Playgroud)

但我会反对它.相反,请保留允许域名的白名单.让我们说:

allowed = [ "X", "Y", "A.Z" ];
Run Code Online (Sandbox Code Playgroud)

然后,如果您收到您的请求,X请回复:

Access-Control-Allow-Origin: X
Run Code Online (Sandbox Code Playgroud)

如果您收到A.Z您的回复,请回复:

Access-Control-Allow-Origin: A.Z
Run Code Online (Sandbox Code Playgroud)

如果您从域中收到不允许的请求,请回复错误或不响应CORS策略.

所有XHR请求都将发送Origin标头,因此请使用它.而且您只需要为OPTIONS请求发送CORS策略标头,而不是后面的GET/POST/HEAD请求.


我看到的主要问题是您公开了所有域名.也许你有一个安全的管理域,如:https://admin.mydomain.com,或者你有一个尚未准备好发布的产品网站.您不希望包含对于手头请求不是绝对必要的任何内容.

而且*只是非常懒惰.


  • 您的答案并未解释允许所有域的安全隐患 (8认同)

bri*_*out 2

除了 的csauve一个之外,所有回复都没有回答我原来的问题。

回答我的问题;看来只要Access-Control-Allow-Credentials不设置就不存在安全问题。

(这让我想知道为什么规范在Access-Control-Allow-Credentials未设置时需要预检?)