CORS 是一种安全的跨域 AJAX 请求方式吗?

IT技术 javascript ajax cross-domain cors
2021-02-01 06:02:50

在阅读了 CORS(跨域资源共享)之后,我不明白它是如何提高安全性的。如果发送了正确的 ORIGIN 标头,则允许跨域 AJAX 通信。例如,如果我发送

来源:http : //example.com

服务器检查此域是否在白名单中,如果是,则检查标题:

Access-Control-Allow-Origin: [在这里接收到 url]

与响应一起发回(这是简单的情况,也有预先准备好的请求,但问题是相同的)。

这真的安全吗?如果有人想接收信息,伪造一个 ORIGIN 标头似乎是一项非常微不足道的任务。该标准还表示,该策略是在浏览器中强制执行的,如果 Access-Control-Allow-Origin 不正确,则会阻止响应。显然,如果有人试图获取该信息,他将不会使用标准浏览器来阻止它。

6个回答

目的是为了防止这种情况——

  • 你去网站X
  • 网站 X 的作者编写了一个邪恶的脚本,该脚本会发送到您的浏览器
  • 在您的浏览器上运行的脚本会登录到您的银行网站并执行恶意操作,并且因为它在您的浏览器中运行时它有权这样做。

想法是您银行的网站需要某种方式来告诉您的浏览器是否应该信任网站 X 上的脚本来访问您银行的页面。

@pootzko:在您的情况下,恶意网站 X 将没有银行网站的有效会话。即使受害者登录了他的银行(例如在另一个选项卡中),恶意站点 X 也无法访问该会话,因为浏览器强制执行 cookie 策略:浏览器永远不会发送会话 cookie银行到网站 X。
2021-03-22 06:02:50
@luigi7up:不,CORS 不保护任何东西,实际上它通过定义 SOP 的例外来“削弱”安全性。Access-Control-Allow-Origin其起点(在指定的标头指定Origin报头)被允许访问该资源。通常只允许具有相同来源的请求这样做。这里最重要的部分是:允许/拒绝是由浏览器强制执行的,而不是服务器。这意味着Access-Control-Allow-Origin保护您的浏览器,而不是服务器上的资源或服务器本身。
2021-03-26 06:02:50
你的回答也很清楚,谢谢。我无法投票,因为它需要 15 个声望。
2021-04-02 06:02:50
那么,CORS 不是在保护网站 X 上的应用程序的完整性,而是在保护 BANK 的完整性,即 Web X 是可信的,可以对 BANK 进行 API 调用?
2021-04-06 06:02:50
什么阻止网站 X 的作者通过他的网站后端将您登录到银行,然后将其用作代理?这只是他必须创建的附加层,但我猜它会完全规避他在浏览器中遇到的 CORS 问题。以一种非常简单的方式..
2021-04-09 06:02:50

只是添加@jcoder 的答案,Origin标题的全部意义不是保护服务器上请求的资源。该任务取决于服务器本身通过其他方式,正是因为攻击者确实能够使用适当的工具来欺骗此标头。

该点Origin报头是为了保护用户。场景如下:

  • 攻击者创建恶意网站 M

  • 用户 Alice 被诱骗连接到 M,其中包含一个脚本,该脚本尝试通过在实际支持 CORS 的服务器 B 上的 CORS 执行某些操作

  • B 的Access-Control-Allow-Origin标头中可能没有 M ,为什么会这样?

  • 关键是 M 无法欺骗或覆盖Origin标头,因为请求是由 Alice 的浏览器发起的。所以她的浏览器会将(正确的)设置Origin为 M,这不在Access-Control-Allow-OriginB 中,因此请求将失败。

Alice 可以Origin自己更改标题,但她为什么要更改,因为这意味着她在伤害自己?

TL;DR:Origin标题保护无辜的用户。它不保护服务器上的资源。攻击者可以在他自己的机器上欺骗它,但不能在不受他控制的机器上欺骗它。

服务器仍应保护其资源,因为匹配的Origin标头并不意味着授权访问。但是,Origin不匹配标头意味着未经授权的访问。

最佳答案 丹尼尔。这就是 CORS 的全部意义:“关键是,M 无法欺骗或覆盖 Origin 标头,因为请求是由 ALICE 的浏览器发起的。所以她的浏览器会将(正确的)Origin 设置为 M,这不在 B 的 Access-Control-Allow-Origin 中,因此请求将失败。”
2021-03-26 06:02:50
为什么这不是选择的答案?这显然是最好的。这个答案中提到的第四点是海报真正要求的。
2021-03-27 06:02:50
非常好的答案。最好的整体恕我直言。
2021-04-07 06:02:50

您不能在 Web 浏览器中使用 JavaScript 伪造 Origin 标头。CORS 旨在防止这种情况发生。

在 Web 浏览器之外,这无关紧要。它并非旨在阻止人们获取对公众可用的数据。如果没有公众获得它,您就不能将其公开给公众。

它的设计是为了给定:

  • Alice,一个提供 API 的人,旨在通过 Ajax 访问
  • 鲍勃,一个有网络浏览器的人
  • 查理,第三方运行自己的网站

如果 Bob 访问 Charlie 的网站,则 Charlie 无法将 JS 发送到 Bob 的浏览器,以便它从 Alice 的网站获取数据并将其发送给 Charlie。

如果 Bob 在 Alice 的网站上拥有一个用户帐户,允许他执行诸如发表评论、删除数据或查看公众无法获得的数据之类的操作,则上述情况变得更加重要——因为没有保护,Charlie 的 JS 可以告诉 Bob 的浏览器在 Bob 的背后这样做(然后将结果发送给 Charlie)。

如果您想阻止未经授权的人查看数据,则需要使用密码、SSL 客户端证书或其他一些基于身份的身份验证/授权方法来保护它。

基本上 CORS 或跨域资源共享和授权是两个独立的事情。正如首字母缩略词所暗示的那样,它实际上是为了允许跨源共享。是否实际允许客户端执行此操作由您的授权逻辑来确定。
2021-04-11 06:02:50

同源策略的目的不是阻止人们访问网站内容;如果有人想这样做,他们甚至不需要浏览器。关键是阻止客户端脚本在没有必要访问权限的情况下访问另一个域上的内容。有关同源策略,请参阅维基百科条目

@luigi7up:是的,CORS 正好相反。它允许网站所有者从多个受信任的域中授予对其服务的访问权限。
2021-03-19 06:02:50
“重点是阻止客户端脚本访问另一个域上的内容”,这已通过同源策略解决。不?我的意思是我的网站向您发送了一些 JS,而您的浏览器将不允许对其他域的 ajax 调用。这是同源策略。CORS 正在做非常对立的事情 - 允许我的 ajax 访问另一个域。我在这里错过了一些巨大的东西:)
2021-03-20 06:02:50

“在阅读了 CORS 之后,我不明白它是如何提高安全性的。”

CORS 不会提高安全性。CORS 为服务器提供了一种机制来告诉浏览器它们应该如何被外部域访问,并且它尝试以与 CORS 之前存在的浏览器安全模型(即同源策略)一致的方式来实现。

但是同源策略和 CORS 的范围有限。具体来说,CORS 规范本身没有拒绝请求的机制。它可以使用标头告诉浏览器不要让来自外部域的页面读取响应。而且,在预检请求的情况下,它可以要求浏览器不要向它发送来自外部域的某些请求。但是 CORS 没有指定服务器拒绝(即不执行)实际请求的任何方式。

让我们举个例子。用户A通过 cookie登录到站点用户加载恶意网站M,它试图提交,做了一个表格POSTA会发生什么?好吧,不管有没有 CORS,有没有M被允许的域,浏览器都会将请求发送到A用户的授权 cookie,服务器将执行恶意行为POST,就像用户发起的一样。

这种攻击称为跨站请求伪造,CORS 本身没有采取任何措施来缓解它。这就是如果您允许代表用户更改数据的请求,CSRF 保护如此重要的原因。

现在,Origin标头的使用可以成为您的 CSRF 保护的重要组成部分。事实上,检查它是当前多管齐下 CSRF 防御建议的一部分但是Origin标头的使用不属于 CORS 规范。

总之,CORS 是将现有同源策略安全模型扩展到其他接受域的有用规范。它不会增加安全性,并且站点需要与 CORS 之前相同类型的防御机制。