Javascript CORS 是一种安全的跨域 AJAX 请求方式吗?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4850702/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Is CORS a secure way to do cross-domain AJAX requests?
提问by Gibarian2001
After reading about CORS (Cross-Origin Resource Sharing), I don't understand how it improves security. Cross-Domain AJAX communication is allowed if the correct ORIGIN header is sent. As an example, if I send
在阅读了 CORS(跨域资源共享)之后,我不明白它是如何提高安全性的。如果发送了正确的 ORIGIN 标头,则允许跨域 AJAX 通信。例如,如果我发送
ORIGIN: http://example.com
来源:http: //example.com
The server checks if this domain is in the white list and, if it is, header:
服务器检查此域是否在白名单中,如果是,则检查标题:
Access-Control-Allow-Origin: [received url here]
Access-Control-Allow-Origin: [此处接收到 url]
is sent back, together with the response (This is the simple case, there are also prefighted requests, but the question is the same).
与响应一起发回(这是简单的情况,也有预先准备好的请求,但问题是相同的)。
Is this really secure? If someone wants to receive the information, faking an ORIGIN headers seems like a really trivial task. Also the standard says that the policy is enforced in the browser, blocking the response if Access-Control-Allow-Origin is not correct. Obviously if anyone is trying to get that info, he will not use a standard browser to block it.
这真的安全吗?如果有人想接收信息,伪造 ORIGIN 标头似乎是一项非常简单的任务。该标准还表示,该策略是在浏览器中强制执行的,如果 Access-Control-Allow-Origin 不正确,则会阻止响应。显然,如果有人试图获取该信息,他将不会使用标准浏览器来阻止它。
采纳答案by Quentin
You can't fake an Origin header with JavaScript in a web browser. CORS is designed to prevent that.
您不能在 Web 浏览器中使用 JavaScript 伪造 Origin 标头。CORS 旨在防止这种情况发生。
Outside of a web browser, it doesn't matter. It isn't designed to stop people from getting data that is available to the public. You can't expose it to the public without members of the public getting it.
在 Web 浏览器之外,这无关紧要。它并非旨在阻止人们获取对公众可用的数据。如果没有公众获得它,您就不能将其公开给公众。
It is designed so that given:
它的设计是为了给定:
- Alice, a person providing an API designed to be accessed via Ajax
- Bob, a person with a web browser
- Charlie, a third party running their own website
- Alice,提供可通过 Ajax 访问的 API 的人
- 鲍勃,一个有网络浏览器的人
- 查理,第三方运行自己的网站
If Bob visits Charlie's website, then Charlie cannot send JS to Bob's browser so that it fetches data from Alice's website and sends it to Charlie.
如果 Bob 访问 Charlie 的网站,则 Charlie 无法将 JS 发送到 Bob 的浏览器,以便它从 Alice 的网站获取数据并将其发送给 Charlie。
The above situation becomes more important if Bob has a user account on Alice's website which allows him to do things like post comments, delete data, or see data that is notavailable to the general public — since without protection, Charlie's JS could tell Bob's browser to do that behind Bob's back (and then send the results to Charlie).
如果 Bob 在 Alice 的网站上拥有一个用户帐户,允许他执行诸如发表评论、删除数据或查看公众无法获得的数据之类的操作,则上述情况变得更加重要——因为在没有保护的情况下,Charlie 的 JS 可以告诉 Bob 的浏览器在 Bob 背后这样做(然后将结果发送给 Charlie)。
If you want to stop unauthorized people from seeing the data, then you need to protect it with passwords, SSL client certs or some other means of identity-based authentication/authorization.
如果您想阻止未经授权的人查看数据,则需要使用密码、SSL 客户端证书或其他一些基于身份的身份验证/授权方法来保护它。
回答by jcoder
The purpose is to prevent this -
目的是为了防止这种情况——
- You go to website X
- The author of website X has written an evil script which gets sent to your browser
- that script running on your browser logs onto your bank website and does evil stuff and because it's running as youin your browser it has permission to do so.
- 你去网站X
- 网站 X 的作者编写了一个邪恶的脚本,该脚本会发送到您的浏览器
- 在您的浏览器上运行的脚本会登录到您的银行网站并执行恶意操作,并且因为它在您的浏览器中像您一样运行,所以它有权这样做。
The ideas is that your bank's website needs some way to tell your browser if scripts on website X should be trusted to access pages at your bank.
想法是您的银行网站需要某种方式来告诉您的浏览器是否应该信任网站 X 上的脚本来访问您银行的页面。
回答by daniel f.
Just to add on @jcoder 's answer, the whole point of the Origin
header isn't to protect the resources requested on a server. That task is up to the server itself via other means exactly because an attacker is indeed able to spoof this header with the appropriate tools.
只是添加@jcoder 的答案,Origin
标题的全部意义不是保护服务器上请求的资源。该任务取决于服务器本身通过其他方式,正是因为攻击者确实能够使用适当的工具来欺骗此标头。
The point of the Origin
header is to protect the user.
The scenario is the following:
该点Origin
报头是为了保护用户。场景如下:
an attacker creates a malicious website M
a user Alice is tricked to connect to M, which contains a script that tries to perform some actions through CORS on a server B that actually supports CORS
B will probably not have M in its
Access-Control-Allow-Origin
header, cause why would it?The pivotal point is that M has no means to spoof or overwrite the
Origin
header, because the requests are initiated by Alice's browser. So her browser will set the (correct)Origin
to M, which is not in theAccess-Control-Allow-Origin
of B, therefore the request will fail.
攻击者创建恶意网站 M
用户 Alice 被诱骗连接到 M,其中包含一个脚本,该脚本尝试通过 CORS 在实际支持 CORS 的服务器 B 上执行某些操作
B 的
Access-Control-Allow-Origin
标头中可能没有 M,这是为什么呢?关键是 M 无法欺骗或覆盖
Origin
标头,因为请求是由 Alice 的浏览器发起的。所以她的浏览器会将(正确的)设置Origin
为 M,而 M 不在Access-Control-Allow-Origin
B 中,因此请求将失败。
Alice could alter the Origin
header herself, but why would she, since it would mean she is harming herself?
Alice 可以Origin
自己更改标题,但她为什么要更改,因为这意味着她在伤害自己?
TL;DR: The Origin
header protects the innocent user. It does not secure resources on a server. It is spoofable by an attacker on his own machine, but it cannot be spoofed on a machine not under his control.
TL;DR:Origin
标头保护无辜的用户。它不保护服务器上的资源。攻击者可以在他自己的机器上欺骗它,但不能在不受他控制的机器上欺骗它。
Servers should still protect their resources, as a matching Origin
header doesn't mean an authorized access. However, a Origin
header that does NOT match means an unauthorized access.
服务器仍应保护其资源,因为匹配的Origin
标头并不意味着授权访问。但是,Origin
不匹配的标头意味着未经授权的访问。
回答by Andy E
The purpose of the same origin policy isn't to stop people from accessing website content generally; if somebody wants to do that, they don't even need a browser. The point is to stop client scriptsaccessing content on another domain without the necessary access rights. See the Wikipedia entry for Same Origin Policy.
同源策略的目的不是阻止人们访问网站内容;如果有人想这样做,他们甚至不需要浏览器。关键是阻止客户端脚本在没有必要访问权限的情况下访问另一个域上的内容。有关同源政策,请参阅维基百科条目。
回答by Kevin Christopher Henry
After reading about CORS, I don't understand how it improves security.
在阅读了 CORS 之后,我不明白它是如何提高安全性的。
CORS does not improve security. CORS provides a mechanism for servers to tell browsers how they should be accessed by foreign domains, and it tries to do so in a way that is consistent with the browser security model that existed before CORS (namely the Same Origin Policy).
CORS 不会提高安全性。CORS 为服务器提供了一种机制来告诉浏览器它们应该如何被外部域访问,并且它尝试以与 CORS 之前存在的浏览器安全模型(即同源策略)一致的方式这样做。
But the Same Origin Policy and CORS have a limited scope. Specifically, the CORS specificationitself has no mechanism for rejecting requests. It can use headers to tell the browser not to let a page from a foreign domain read a response. And, in the case of preflight requests, it can ask the browser not to send it certain requests from a foreign domain. But CORS doesn't specify any means for the server to reject (that is, not execute) an actual request.
但是同源策略和 CORS 的范围有限。具体来说,CORS 规范本身没有拒绝请求的机制。它可以使用标头告诉浏览器不要让来自外部域的页面读取响应。而且,在预检请求的情况下,它可以要求浏览器不要向它发送来自外部域的某些请求。但是 CORS 没有指定服务器拒绝(即不执行)实际请求的任何方式。
Let's take an example. A user is logged in to site A
via a cookie. The user loads malicious site M
, which tries to submit a form that does a POST
to A
. What will happen? Well, with or without CORS, and with or without M
being an allowed domain, the browser will send the request to A
with the user's authorization cookie, and the server will execute the malicious POST
as if the user initiated it.
让我们举个例子。用户A
通过 cookie登录站点。用户加载恶意网站M
,它试图提交,做了一个表格POST
来A
。会发生什么?好吧,不管有没有 CORS,有没有M
被允许的域,浏览器都会将请求发送到A
用户的授权 cookie,服务器将执行恶意行为POST
,就像用户发起的一样。
This attack is called Cross-Site Request Forgery, and CORS itself does nothing to mitigate it. That's why CSRF protections are so important if you allow requests to change data on behalf of users.
这种攻击称为跨站请求伪造,CORS 本身没有采取任何措施来缓解它。这就是如果您允许代表用户更改数据的请求,CSRF 保护如此重要的原因。
Now, the use of the Origin
header can be an important part of your CSRF protection. Indeed, checking it is part of the current recommendation for multi-pronged CSRF defense. But that use of the Origin
header falls outside the CORS specification.
现在,Origin
标头的使用可以成为您的 CSRF 保护的重要组成部分。事实上,检查它是当前多管齐下 CSRF 防御建议的一部分。但是Origin
标头的使用不属于 CORS 规范。
In sum, CORS is a useful specification for extending the existing Same Origin Policy security model to other accepted domains. It doesn't add security, and sites need the same kinds of defense mechanisms that they did before CORS.
总之,CORS 是将现有同源策略安全模型扩展到其他接受域的有用规范。它不会增加安全性,并且站点需要与 CORS 之前相同类型的防御机制。
回答by alaboudi
I am late to answer but I don't think any post here really provides the sought answer. The biggest takeaway should be that the browser is the agent that is writing the origin
header value. An evil script cannot write the origin
header value. When the server responds back with a Access-Control-Allow-Origin
header, the browser tries to ensure that this header contains the origin
value sent earlier. If not, it triggers an error and does not return the value back to the requesting script. The other answers to this question present a good scenario to when you would like to deny an answer back to the evil script.
我回答晚了,但我认为这里的任何帖子都没有真正提供所寻求的答案。最大的收获应该是浏览器是写入origin
标头值的代理。恶意脚本无法写入origin
标头值。当服务器用Access-Control-Allow-Origin
标头响应时,浏览器会尝试确保该标头包含origin
先前发送的值。如果不是,它会触发错误并且不会将该值返回给请求脚本。这个问题的其他答案提供了一个很好的场景,当您想拒绝对邪恶脚本的回答时。
@daniel f also provides a good answer to the question
@daniel f 也很好地回答了这个问题