似乎 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 的预飞行没有意义。是笑话吗?的主要内容,如果未能解决你的问题,请参考以下文章