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

Dom*_*nic 35 security http xmlhttprequest cross-domain cors

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

为什么?

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

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

Sri*_*nan 58

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

  1. 它无法从我使用的其他网站上读取我的个人数据.想想attacker.com阅读gmail.com
  2. 它无法代表我在我使用的其他网站执行操作.想想attacker.com从我在bank.com上的账户转账

同源政策解决了第一个问题.第二个问题称为跨站点请求伪造,并且无法通过当前的跨域限制来解决.

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

  • 规则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. 众所周知,滥用<script>标签称为JSONP,您可以在其中与跨域服务器串联,以便您可以"阅读"跨域.但是,如果没有跨域服务器的明确参与,您将无法通过<script>标记读取响应

  4. <link>对于样式表,工作主要类似于<script>标记,除了响应被评估为CSS.通常,您无法读取响应 - 除非响应在某种程度上恰好是格式良好的CSS.

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

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

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

简而言之,同一起源政策是一致的.如果您在未经跨域网站明确许可的情况下找到了提出跨域请求阅读响应的方法,那么您将成为全世界的头条新闻.

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

要使gmail显示个性化数据,它需要来自浏览器的cookie.某些站点使用HTTP基本身份验证,其中凭据存储在浏览器中.

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

  • @Domenic - 查看我的更新.当客户端代码发出请求时,cookie会隐式传递.这些cookie允许跨域服务器识别用户,从而返回个性化数据.服务器端代理无法访问这些cookie,因此无法读取个人数据. (2认同)