为什么浏览器API会限制跨域请求?

时间:2012-02-10 04:46:06

标签: security http xmlhttprequest cross-domain cors

XMLHttpRequest要求CORS跨域工作。类似于Web字体,WebGL纹理和其他一些东西。通常,所有新API似乎都有此限制。

为什么?

这很容易规避:所需要的只是一个简单的服务器端代理。换句话说,不禁止服务器端代码执行跨域请求;为什么是客户端代码?这对任何人都有什么安全保障?

它是如此不一致:我不能XMLHttpRequest,但我可以<script src><link rel><img src><iframe>。什么限制XHR等甚至完成?

3 个答案:

答案 0 :(得分:56)

如果我访问恶意网站,我想确定:

  1. 它无法从我使用的其他网站上读取个人数据。想想attacker.com阅读gmail.com
  2. 在我使用的其他网站上,它无法代表我执行操作。想想attacker.com从我在bank.com上的账户转账资金
  3. 同源政策解决了第一个问题。第二个问题称为跨站点请求伪造,并且无法通过当前的跨域限制来解决。

    同一原产地政策总体上符合以下规则 -

    • 规则1:不允许您从其他域中读取任何内容
    • 规则2:允许您将您想要的任何内容写入其他域,但规则#1不允许您阅读响应。
    • 规则3:您可以自由地进行跨域GET请求和POST请求,但无法控制HTTP标头

    让我们看看您列出的各种内容如何符合上述规则:

    1. <img>标签可让您发出HTTP请求,但除了简单地显示图像之外,无法读取图像的内容。例如,如果我执行此操作<img src="http://bank.com/get/latest/funds"/>,请求将通过(规则2)。但是攻击者无法看到我的平衡(规则1)。

    2. <script>标记主要与<img>类似。如果您执行<script src="http://bank.com/get/latest/funds">之类的操作,请求将会完成。浏览器还会尝试将响应解析为JavaScript,并且会失败。

    3. 众所周知滥用名为JSONP的<script>标记,您可以在其中与跨域服务器串联,以便您可以“阅读”跨域。但是,如果没有跨域服务器的明确参与,您无法通过<script>标记

    4. 阅读回复 样式表的
    5. <link>主要与<script>标签一样,除了响应被评估为CSS。一般情况下,你无法读取响应 - 除非响应在某种程度上恰好是格式良好的CSS。

    6. <iframe>本质上是一个新的浏览器窗口。您无法读取跨域iframe的HTML。顺便提一下,您可以更改跨域iframe的网址,但无法读取该网址。请注意它是如何遵循我上面提到的两个规则的。

    7. XMLHttpRequest是发出HTTP请求的最通用的方法。这完全在开发人员的控制之下;浏览器不对响应做任何事情。例如,在<img><script><link>的情况下,浏览器采用特定格式,并且通常会对其进行适当验证。但在XHR中,没有规定的响应格式。因此,除非跨域网站明确允许,否则浏览器会强制执行相同的原始策略并阻止您阅读响应。

    8. 通过font-face的字体是异常的。 AFAIK,只有Firefox需要选择加入行为;其他浏览器允许您像使用图像一样使用字体。

    9. 简而言之,相同的原产地政策是一致的。如果您发现跨域请求的方式在没有跨域网站明确许可的情况下阅读回复 - 您将成为全世界的头条新闻。

      编辑:为什么我不能通过服务器端代理解决所有这些问题?

      要让Gmail显示个性化数据,它需要您浏览器提供的Cookie。某些站点使用HTTP基本身份验证,其中凭据存储在浏览器中。

      服务器端代理无法访问cookie或基本身份验证凭据。因此,即使它可以发出请求,服务器也不会返回用户特定的数据。

答案 1 :(得分:3)

考虑这种情况...

  1. 你去了我的恶意网站。
  2. 我的网站向您的银行网站提供XHR,并要求提供银行转帐表格。
  3. XHR会读取阻止CSRF的令牌,并将表单与安全令牌一起发布,并将一笔款项转入我的帐户。
  4. (I)利润!!!
  5. 如果没有相同的原始策略,您仍然可以POST该表单,但您将无法请求阻止CSRF的CSRF令牌。

    服务器端代码无法在客户端的计算机上运行。

答案 2 :(得分:2)

XHR的主要问题是他们不能只发送请求,但您也可以阅读响应。几乎可以发送任意请求。但阅读他们的回答并非如此。这就是原始XHR根本不允许任何跨源请求的原因。

稍后,当出现对XHR的跨源请求的需求时,建立CORS以允许在特定条件下的跨源请求。一个条件是特定请求方法,请求标头字段和包含用户凭证的请求需要所谓的预检请求,客户​​端可以使用该请求来检查服务器是否允许该请求。有了这个,服务器就能够限制对特定来源的访问,否则任何来源都可以发送请求。