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

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

ORIGIN: http : //example.com

服务器检查这个域是否在白名单中,如果是,则为:

Access-Control-Allow-Origin:[在此处收到url]

被送回,连同回应(这是简单的情况,也有前瞻性的请求,但问题是一样的)。

这真的很安全吗? 如果有人想要收到这些信息,伪造一个ORIGIN标题看起来像是一件非常简单的事情。 此外,该标准还指出,如果Access-Control-Allow-Origin不正确,则在浏览器中执行策略,阻止响应。 显然,如果有人试图获取这些信息,他不会使用标准浏览器来阻止它。

它不是为了阻止人们获取数据而devise的。 没有人得到它,你不能暴露它。

它是这样devise的:

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

如果Bob访问Charlie的网站,那么Charlie就不能将JS发送给Bob的浏览器,以便从Alice的网站获取数据并将其发送给Charlie。

如果鲍勃在爱丽丝的网站上有一个用户帐户,允许他进行评论或删除数据等事情,那么上述情况会变得更加重要 – 因为没有保护,查理可以告诉鲍勃的浏览器在鲍勃的背后这样做。

如果您想阻止未经授权的人查看数据,那么您需要使用密码,SSL客户端证书或其他一些基于身份的身份validation/授权的方式进行保护。

目的是防止这一点 –

  • 你去网站X
  • 网站X的作者写了一个邪恶的脚本,发送到您的浏览器
  • 在您的浏览器上运行的脚本login到您的银行网站,做恶意的东西,因为它正在浏览器中运行它有权这样做。

这个想法是,您的银行网站需要一些方法来告诉您的浏览器,如果网站X上的脚本应该被信任访问您银行的网页。

只要添加@jcoder的答案, Origin头部的全部内容不是保护服务器上请求的资源,这个任务取决于服务器本身,这完全是因为攻击者确实能够欺骗这个头部适当的工具。

Origin标题的要点是保护用户。 情况如下:

  • 攻击者Marie创build一个恶意网站M

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

  • B的Access-Control-Allow-Origin头部可能不会有M,这是为什么呢?

  • 关键在于,M没有办法欺骗或覆盖Origin头部,导致请求由ALICE的浏览器启动。 因此,她的浏览器会将(正确) Origin为M,这不在B的Access-Control-Allow-Origin中,因此请求将失败。

现在,爱丽丝可以自己改变Origin标题,但是为什么她呢,因为这意味着她正在伤害自己?

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

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

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

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

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

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

我们来举个例子。 用户通过cookielogin到站点A 用户加载恶意网站M ,该网站试图将提交表单的邮件提交给A 会发生什么? 那么,有或没有CORS,有或没有M是一个允许的域,浏览器将用用户的授权cookie发送请求到A ,并且服务器将执行恶意的POST ,就好像用户启动它一样。

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

现在, Origin头文件的使用可以成为您的CSRF保护的重要组成部分。 事实上,检查它是目前多pipe齐下的CSRF防御build议的一部分。 但是Origin头文件的使用不在CORS规范之内。

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

我迟到了,但我不认为这里的任何职位真的提供了寻求的答案。 最大的问题应该是浏览器是编写origin值的代理。 一个邪恶的脚本不能写出origin标题值。 当服务器用Access-Control-Allow-Origin头回应时,浏览器会试图确保这个头包含之前发送的origin值。 如果不是,则会触发错误,并且不会将该值返回给请求脚本。 这个问题的其他答案提出了一个很好的情况,当你想拒绝一个答案回到邪恶的脚本。

@丹尼尔f也提供了一个很好的答案