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



XMLHttpRequest需要CORS跨域工作。同样适用于web字体、WebGL纹理和其他一些东西。一般来说,所有新的API似乎都有这个限制。

为什么?

它很容易规避:只需要一个简单的服务器端代理。换句话说,服务器端代码并没有被禁止进行跨域请求;为什么是客户端代码?这是如何为任何人提供安全保障的?

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

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

  1. 它无法从我使用的其他网站读取我的个人数据。想想attaker.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的URL,但无法读取该URL。注意它是如何遵循我上面提到的两条规则的。

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

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

简而言之,同源政策是一致的。如果你想办法提出跨域请求,并且在未经跨域网站明确许可的情况下阅读响应,你将成为世界各地的头条新闻。

EDIT:为什么我不能用服务器端代理绕过这一切?

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

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

考虑这个场景。。。

  1. 你去我的恶意网站
  2. 我的网站向您的银行网站发送XHR,并要求提供银行转账表格
  3. XHR读取阻止CSRF的令牌,并将表单与安全令牌一起张贴,并将一笔钱转移到我的账户
  4. (I) 利润

如果没有同源策略,您仍然可以POST该表单,但您将无法请求阻止CSRF的CSRF令牌。

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

XHR的主要问题是,它们不仅可以发送请求,而且还可以读取响应。发送几乎任意的请求已经成为可能。但阅读他们的回复却并非如此。这就是为什么最初的XHR根本不允许任何跨源请求。

后来,当出现对XHR跨来源请求的需求时,CORS被建立起来,允许在特定条件下进行跨来源请求。一个条件是,特定的请求方法、请求头字段和将包含用户凭据的请求需要一个所谓的飞行前请求,客户端可以通过该请求检查服务器是否允许该请求。这样,服务器就可以限制对特定来源的访问,否则任何来源都可以发送请求。

相关内容

  • 没有找到相关文章

最新更新