引入预检 CORS 请求的动机是什么?

2022-01-15 00:00:00 cors http html ajax preflight

跨域资源共享是一种允许网页向另一个域发出 XMLHttpRequests 的机制(来自 维基百科).

Cross-origin resource sharing is a mechanism that allows a web page to make XMLHttpRequests to another domain (from Wikipedia).

过去几天我一直在摆弄 CORS,我想我对一切的工作原理已经有了很好的了解.

I've been fiddling with CORS for the last couple of days and I think I have a pretty good understanding of how everything works.

所以我的问题不是关于 CORS/preflight 的工作原理,而是关于将 preflights 作为新的请求类型提出的原因.我看不出为什么服务器 A 需要向服务器 B 发送预检 (PR) 只是为了确定是否会接受真正的请求 (RR) - B 肯定有可能接受/拒绝 RR任何先前的 PR.

So my question is not about how CORS / preflight work, it's about the reason behind coming up with preflights as a new request type. I fail to see any reason why server A needs to send a preflight (PR) to server B just to find out if the real request (RR) will be accepted or not - it would certainly be possible for B to accept/reject RR without any prior PR.

经过一番搜索,我在 这条信息a href="http://www.w3.org" rel="noreferrer">www.w3.org (7.1.5):

After searching quite a bit I found this piece of information at www.w3.org (7.1.5):

为了保护资源免受在本规范存在之前不能来自某些用户代理的跨域请求发出预检请求以确保资源知道这一点规范.

我发现这是有史以来最难理解的句子.我的解释(最好称其为最佳猜测")是,它是关于保护服务器 B 免受来自不了解规范的服务器 C 的请求.

I find this is the hardest to understand sentence ever. My interpretation (should better call it 'best guess') is that it's about protecting server B against requests from server C that is not aware of the spec.

有人可以解释一个场景/展示一个 PR + RR 比单独使用 RR 解决的问题吗?

Can someone please explain a scenario / show a problem that PR + RR solves better than RR alone?

推荐答案

我花了一些时间对预检请求的目的感到困惑,但我想我现在明白了.

I spent some time being confused as to the purpose of the preflight request but I think I've got it now.

关键的见解是预检请求不是安全的事情.相反,它们是不改变规则的东西.

The key insight is that preflight requests are not a security thing. Rather, they're a not-changing-the-rules thing.

预检请求与安全无关,它们与现在正在开发的应用程序无关,具有 CORS 意识.相反,预检机制有益于在不了解 CORS 的情况下开发的服务器,并且它充当客户端和服务器之间的健全性检查,它们都支持 CORS.CORS 的开发人员认为那里有足够多的服务器依赖于他们永远不会收到的假设,例如一个跨域删除请求,他们发明了预检机制以允许双方选择加入.他们认为,如果简单地启用跨域调用,替代方案会破坏太多现有应用程序.

Preflight requests have nothing to do with security, and they have no bearing on applications that are being developed now, with an awareness of CORS. Rather, the preflight mechanism benefits servers that were developed without an awareness of CORS, and it functions as a sanity check between the client and the server that they are both CORS-aware. The developers of CORS felt that there were enough servers out there that were relying on the assumption that they would never receive, e.g. a cross-domain DELETE request that they invented the preflight mechanism to allow both sides to opt-in. They felt that the alternative, which would have been to simply enable the cross-domain calls, would have broken too many existing applications.

这里有三种情况:

  1. 旧服务器,不再开发,在 CORS 之前开发.这些服务器可能会假设他们永远不会收到,例如一个跨域的 DELETE 请求.这种情况是预检机制的主要受益者. 是的,这些服务可能已经被恶意或不合格的用户代理滥用(CORS 并没有改变这一点),但是在使用 CORS 的世界中预检机制提供了额外的健全性检查",这样客户端和服务器就不会因为 Web 的底层规则发生变化而中断.

  1. Old servers, no longer under development, and developed before CORS. These servers may make assumptions that they'll never receive e.g. a cross-domain DELETE request. This scenario is the primary beneficiary of the preflight mechanism. Yes these services could already be abused by a malicious or non-conforming user agent (and CORS does nothing to change this), but in a world with CORS the preflight mechanism provides an extra 'sanity check' so that clients and servers don't break because the underlying rules of the web have changed.

仍在开发中的服务器,但其中包含大量旧代码,并且无法/不希望审核所有旧代码以确保其在跨域环境中正常工作.这种情况允许服务器逐步选择加入 CORS,例如通过说现在我将允许这个特定的标头"、现在我将允许这个特定的 HTTP 动词"、现在我将允许发送 cookie/auth 信息"等.这种情况得益于预检机制.

Servers that are still under development, but which contain a lot of old code and for which it's not feasible/desirable to audit all the old code to make sure it works properly in a cross-domain world. This scenario allows servers to progressively opt-in to CORS, e.g. by saying "Now I'll allow this particular header", "Now I'll allow this particular HTTP verb", "Now I'll allow cookies/auth information to be sent", etc. This scenario benefits from the preflight mechanism.

以 CORS 意识编写的新服务器.根据标准安全实践,服务器必须在面对任何传入请求时保护其资源——服务器不能相信客户端不会做恶意事情.这种情况不会从预检机制中受益:预检机制不会为已正确保护其资源的服务器带来额外的安全性.

New servers that are written with an awareness of CORS. According to standard security practices, the server has to protect its resources in the face of any incoming request -- servers can't trust clients to not do malicious things. This scenario doesn't benefit from the preflight mechanism: the preflight mechanism brings no additional security to a server that has properly protected its resources.

相关文章