【问题标题】:Safe implementation of script tag hack to do XSS?安全实施脚本标签黑客来做 XSS?
【发布时间】:2011-04-03 20:15:08
【问题描述】:

像许多开发人员一样,我想让服务器“A”提供的 JavaScript 与服务器“B”上的 Web 服务通信,但被 same origin policy 的当前化身所阻碍。克服这个(我能找到的)最安全的方法是一个服务器脚本,它位于服务器“A”上并充当它和“B”之间的代理。但是如果我想在各种客户环境(RoR、PHP、Python、.NET 等)中部署这个 JavaScript 并且无法为所有这些环境编写代理脚本,我该怎么办?

使用 JSONP,some people say。好吧,Doug Crockford 指出 on his websitein interviews 脚本标签 hack(由 JSONP 使用)是绕过同源策略的不安全方法。 “A”提供的脚本无法验证“B”是他们所说的身份,并且它返回的数据不是恶意的或将捕获该页面上的敏感用户数据(例如信用卡号)和传给卑鄙的人。这似乎是一个合理的担忧,但如果我只使用脚本标签 hack 并严格使用 JSON 进行通信怎么办?那安全吗?如果不是,为什么不呢?使用 HTTPS 会更安全吗?示例场景将不胜感激。

附录:需要支持 IE6。第三方浏览器扩展不是一种选择。让我们继续解决脚本标签黑客的优点和风险。

【问题讨论】:

  • what if I just use the script tag hack by itself and communicate strictly in JSON? 是什么意思?
  • “A”提供的脚本将包含一个语句,该语句将脚本标记附加到客户端 DOM。该脚本标记将包含一个 AJAX 调用,该调用将从不同域的“B”获取纯 JSON 数据。如果“A”提供的脚本将响应解析为 JSON,那么任何 JavaScript 填充(又名 JSONP、恶意或其他)不会导致解析错误吗?

标签: security cross-domain xss jsonp same-origin-policy


【解决方案1】:

向所有试图回答我问题的人道歉。它是在对脚本标签黑客如何工作的错误假设下进行的。假设可以简单地将脚本标签附加到 DOM,并且该附加脚本标签的 contents 不会受到同源策略的限制。

如果我在发布问题之前费心测试我的假设,我就会知道附加标签的 source 属性 是不受限制的。 JSONP 通过建立将传统 JSON Web 服务响应包装在回调函数中的协议更进一步。

然而,无论脚本标签黑客如何使用,都无法屏蔽恶意代码的响应,因为浏览器会执行返回的任何 JavaScript。在这种情况下,IE、Firefox 和 Webkit 浏览器都不会检查 SSL 证书。据我所知,Doug Crockford 是正确的。从 JavaScript 1.8.5 开始,没有安全的方法来执行跨域脚本。

【讨论】:

    【解决方案2】:

    看看easyXDM,它是一个干净的 JavaScript 库,允许您跨域边界进行通信,而无需任何服务器端交互。它甚至支持开箱即用的 RPC。
    它支持所有“现代”浏览器,以及传输时间

    一个常见的用例是使用它来公开一个 ajax 端点,让您可以毫不费力地进行跨域 ajax(查看首页上的小示例)。

    【讨论】:

      【解决方案3】:

      如果我只使用脚本标签 hack 并严格使用 JSON 进行通信会怎样?那安全吗?如果没有,为什么不呢?

      假设您有两台服务器 - frontend.com 和 backend.com。 frontend.com 包含一个像这样的<script> 标签 - <script src="http://backend.com/code.js"></script>

      当浏览器评估code.js 时,被认为是frontend.com 的一部分,而不是backend.com 的一部分。因此,如果 code.js 包含与 backend.com 通信的 XHR 代码,它将失败

      使用 HTTPS 会更安全吗?示例场景将不胜感激。

      如果您只是将您的 <script src="https://backend.com/code.js> 转换为 https,那么它是任何安全的。如果您页面的其余部分是 http,那么攻击者可以轻松地在页面中间进行人为操作并将该 https 更改为 http - 或者更糟糕的是,包含他自己的 javascript 文件。

      如果您将整个页面及其所有组件转换为 https,它会更安全。但是,如果您足够偏执地做到这一点,那么您也应该偏执地不要依赖外部服务器来获取数据。如果攻击者破坏了 backend.com,他实际上已经在 frontend.com、frontend2.com 和您的所有网站上获得了足够的影响力。

      简而言之,https 是有帮助的,但如果您的后端服务器受到攻击,它对您毫无帮助。

      那么,我有哪些选择?

      1. 在您的每个客户端应用程序上添加一个代理服务器。您不需要编写任何代码,您的网络服务器可以自动为您完成。如果您使用的是 Apache,请查找 mod_rewrite
      2. 如果您的用户使用最新的浏览器,您可以考虑使用Cross Origin Resource Sharing
      3. 正如 The Rook 指出的,您也可以使用 Flash + Crossdomain。或者,您可以使用 Silverlight 及其相当于 Crossdomain。这两种技术都允许您与 javascript 进行通信——因此您只需要编写一个实用程序函数,然后正常的 js 代码就可以工作了。我相信 YUI 已经为此提供了一个 flash 包装器 - 检查 YUI3 IO

      你有什么推荐的?

      我的建议是创建一个代理服务器,并在整个网站中使用 https。

      【讨论】:

        【解决方案4】:

        目前,浏览器供应商对跨域 javascript 的工作方式存在分歧。 Flash 的Crossdomain.xml file 是一个安全且易于使用的选项。大多数语言都有为它们编写的Cross Domain Proxies,它们是开源的。

        一个更邪恶的解决方案是使用 xss 如何传播 Sammy Worm。 XSS 可用于使用 xmlhttprequest 来“读取”远程域。如果其他域添加了<script src="https://YOUR_DOMAIN"></script>,则不需要 XSS。像这样的脚本标签允许您在另一个域的上下文中评估您自己的 JavaScript,这与 XSS 相同。

        同样重要的是要注意,即使有同源策略的限制,您也可以让浏览器将请求传输到任何域,但您无法读取响应。这是 CSRF 的基础。您可以动态地将不可见的图像标签写入页面,以使浏览器触发无限数量的 GET 请求。这种图像标签的使用是攻击者如何在另一个域上使用 XSS 获取documnet.cookie。 CSRF POST 通过构建表单然后在表单对象上调用.submit() 来利用工作。

        要更好地理解 Same Orgin Policy、CSRF 和 XSS,您必须阅读 Google Browser Security Handbook

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2016-09-22
          • 2020-07-28
          • 1970-01-01
          • 2010-12-19
          • 1970-01-01
          • 2017-11-14
          相关资源
          最近更新 更多