似乎 CORS 的预飞行没有意义。是笑话吗?

Posted

技术标签:

【中文标题】似乎 CORS 的预飞行没有意义。是笑话吗?【英文标题】:It seems the pre-flight for CORS doesn't make sense. Is it a joke? 【发布时间】:2016-04-11 14:14:34 【问题描述】:

根据here的样本:

如果请求使用 GET、HEAD 或 POST 以外的方法。此外,如果 POST 用于发送 Content-Type 以外的请求数据 application/x-www-form-urlencoded、multipart/form-data 或 text/plain, 例如如果 POST 请求使用 application/xml 或 text/xml,则请求被预检

所以在下面的示例中,由于 XML Content-Type 和自定义标头X-PINGOTHER 进行了预检:

var invocation = new XMLHttpRequest();
var url = 'http://bar.other/resources/post-here/';
var body = '<?xml version="1.0"?><person><name>Arun</name></person>';

function callOtherDomain()
  if(invocation)
    
      invocation.open('POST', url, true);
      invocation.setRequestHeader('X-PINGOTHER', 'pingpong'); //<====
      invocation.setRequestHeader('Content-Type', 'application/xml'); //<====
      invocation.onreadystatechange = handler;
      invocation.send(body); 
    

但是在所谓的 pre-flight OPTIONS 请求中(下),只通知服务器 HTTP 方法和自定义标头。 没有人告诉服务器XML Content-Type

从逻辑上讲,只要发送了预检请求,就暗示Content-Type不属于不需要预检的3种形式。但是还有许多其他的可能性。 底线是,服务器应该能够知道为什么发送预检请求。

那么服务器如何合理地决定是否允许这个缺少拼图(内容类型)的请求?

【问题讨论】:

如果可能,请将您的代码作为文本而不是图像。 @toasted_flakes 好的,已修复。 【参考方案1】:

CORS几乎总是安全的。引用the Fetch Standard,

对于数据通过 IP 身份验证或 防火墙(不幸的是仍然比较常见),使用 CORS 协议不安全。 (这就是为什么 CORS 协议必须 被发明出来。)

但是,否则使用以下标头是安全的:

访问控制允许来源:*

即使资源基于 cookie 或 HTTP 身份验证,使用上面的标头不会泄露它。它 将与 XMLHttpRequest 等 API 共享资源,就像它一样 已与 curl 和 wget 共享。

也就是说,如果一个资源不能从一个随机的 使用 curl 和 wget 连接到网络的设备 标题不包括在内。但是,如果它可以访问,它是 这样做很好。

因此,服务器不需要知道关于请求的内容类型的任何信息,就可以知道如何响应 OPTIONS 请求。服务器只需要知道:被询问的 URL 是只能通过基于 IP 的身份验证访问,还是在某些防火墙或 Intranet 后面?如果是,那么它应该拒绝 OPTIONS 请求。如果不是,即如果可以使用 curl、wget、telnet 或您最喜欢的 HTTP 库等工具通过公共 Internet 访问资源,那么它应该允许 OPTIONS 请求。这样做只会为浏览器提供与其他工具相同的访问权限。

当随后的 POST 请求进来时,服务器可以做出进一步的决定。例如,服务器可能想要拒绝 Content-Type 错误的 POST。但它总是想这样做。它不想只拒绝来自尊重 CORS 的浏览器的 OPTIONS 请求;相反,它应该拒绝来自任何来源的 POST 请求。

(浏览器之所以特别的原因如下。考虑一个遵循不良安全实践的内部网,并且任何IP地址在一定范围内的人都可以读取,即任何使用公司计算机的人。通常,这没有问题:公司内部使用 curl 的人可以访问数据,而外部使用 curl 的人不能。但是,考虑一下公司内部有人浏览了某个恶意网站,https://evil.com/。如果 evil.com 使用 XHR API 访问@ 987654323@,那么请求将来自特权IP地址,因为它是特权用户计算机上的浏览器发出请求。为了防止这种安全漏洞,发明了CORS协议,以便浏览器不是直接 POST 到http://intranet/secret-data,而是首先执行一个 OPTIONS 请求,整个http://intranet 可能只会说“不,你不能访问这个”,然后 POST 永远不会发生。)

【讨论】:

很难得到,但似乎是对的。我会花更多的时间在上面。谢谢。

以上是关于似乎 CORS 的预飞行没有意义。是笑话吗?的主要内容,如果未能解决你的问题,请参考以下文章

与 API 的连接总是导致 CORS 飞行前错误

为啥这个简单的 CORS 请求会进行飞行前选项检查

我们应该在发送响应时关闭飞行前 Cors 请求的连接吗?

为啥我在 Express 上设置 CORS 时出现飞行前错误?

AWS API Gateway CORS 飞行前检查失败

未触发 CORS 检查的飞行前请求