42

为什么决定使用XMLHTTPRequest进行 XML 调用不应该跨域边界进行调用?您可以从其他域检索 JavaScript、图像、CSS、iframe 以及我能想到的任何其他内容。为什么不允许 Ajax HTTP 请求跨越域边界?考虑到我可以看到它被滥用的唯一方式,这似乎是一个奇怪的限制,那就是如果有人将 Javascript 注入页面。但是,在这种情况下,您可以简单地将 img、script 或 iframe 元素添加到文档中,以使其请求第三方 URL 并将其发送到服务器。

[编辑]

一些答案指出了以下原因,让我们指出他们没有造成不允许这样做的主要原因的原因。

XSRF(Cross Site Request Forgery,又称CSRF、XSRF)

你可以在不使用它的情况下进行 XSRF 攻击。作为一般规则,根本不使用 XMLHTTPRequest,只是因为很难以与所有主流浏览器兼容的方式生成 XMLHTTPRequest。如果您希望他们加载您的 URL,只需向 URL 添加一个 img 标记会容易得多。

发布到第三方网站

<script type="text/javascript">
  $.post("http://some-bank.com/transfer-money.php", 
         { amount: "10000", to_account: "xxxx" })
</script>

可以用

<body onload="document.getElementById('InvisbleForm').submit()"
    <div style="display:none">
        <form id="InvisbleForm" action="http://some-bank.com/transfer-money.php" method="POST">
            <input type="hidden" name="amount" value="10000">
            <input type="hidden" name="to_account" value="xxxxx">
        </form>
    </div>
</body>

JPunyon:为什么要把漏洞留在新功能中

你不会再制造任何不安全感。您只是给想要以某种方式使用它的开发人员带来不便。任何想要将此功能用于邪恶(又名真棒)的人都可以使用其他方法来做到这一点。

结论

我将bobince的答案标记为正确,因为他指出了关键问题。因为 XMLHTTPRequest 允许您使用凭据(cookie)发布到目标站点,并读取从站点发回的数据,以及发送人员凭据,所以您可以编排一些 javascript 来提交一系列表单,包括确认表单, 以及生成的任何随机密钥,这些密钥被放置在适当的位置以防止 XSRF。这样,您可以像银行一样浏览目标站点,而银行的网络服务器将无法判断提交所有这些表单的不仅仅是普通用户。

4

9 回答 9

37

为什么不允许 Ajax HTTP 请求跨越域边界。

因为 AJAX 请求是 (a) 使用用户凭据提交的,并且 (b) 允许调用者读取返回的数据。

正是这些因素的组合可能导致漏洞。有人提议添加一种省略用户凭据的跨域 AJAX。

您可以简单地将 img、script 或 iframe 元素添加到文档中

这些方法都不允许调用者读取返回的数据。

(除了故意设置允许的脚本,允许跨域脚本 - 或者有人犯了一个可怕的错误。)

你可以在不使用它的情况下进行 XSS 攻击。发布到第三方网站

这不是 XSS 攻击。这是一种跨站点请求伪造攻击(XSRF)。有一些已知的方法可以解决 XSRF 攻击,例如包括一次性或加密令牌来验证提交是否来自用户故意,而不是从攻击者代码启动。

如果您允许跨域 AJAX,您将失去此保护措施。攻击代码可以从银行站点请求一个页面,读取其中的任何授权令牌,并在第二个 AJAX 请求中提交它们以执行传输。那是跨站点脚本攻击。

于 2009-01-21T20:53:22.333 回答
8

POST之间的一个重要区别:

<body onload="document.getElementById('InvisbleForm').submit()" ...

而 Ajax 是在执行任何 POST 之后,浏览器将替换页面并且在执行 Ajax 调用之后 - 不是。POST 的结果将是:

  1. 对用户清晰可见。
  2. 攻击将停留在这一点上,因为来自的响应页面my-bank.com将获得控制权。没有银行会实施一键转账

如果允许跨域 Ajax,XSRF 的场景将如下所示:

  1. 用户以某种方式访问www.bad-guy.com​​。
  2. my-bank.com如果在其他浏览器实例中没有打开页面,则攻击不成功。
  3. 但是如果这样的页面被打开并且用户已经输入了他的用户名/密码,这意味着在浏览器的缓存中有这个会话的cookie。
  4. 页面上的 JavaScript 代码www.bad-guy.commy-bank.com.
  5. 对于浏览器,这是一个常规的 HTTP 调用,它必须将 my-bank cookie 发送到my-bank.com并发送它们。
  6. 银行处理此请求是因为它无法将此呼叫与用户的常规活动区分开来。
  7. JavaScript 代码可以读取响应这一事实并不重要。在攻击情况下,这可能不是必需的。真正重要的是,电脑前的用户不会知道这种交互的发生。他会看www.bad-guy.com页面上漂亮的图片。
  8. my-bank.com如果需要,JavaScript 代码会进行其他几次调用。

要点是不需要注入或任何页面篡改。

更好的解决方案可能是允许调用本身但不发送任何 cookie。这是一个非常简单的解决方案,不需要任何广泛的开发。在许多情况下,Ajax 调用会转到未受保护的位置,并且不发送 cookie 不会成为限制。

现在正在讨论的 CORS(跨源资源共享),其中包括发送/不发送 cookie。

于 2012-10-12T23:12:28.730 回答
2

好吧,显然你不是唯一有这种感觉的人......

http://www.google.com/search?q=xmlhttp+cross+site

编辑:上面的搜索链接了一个有趣的讨论:

http://blogs.msdn.com/ie/archive/2008/06/23/securing-cross-site-xmlhttprequest.aspx

似乎正在提议允许跨站点 xmlhttp 请求(IE 8、FF3 等),尽管我希望在我为我的站点编写代码时它们就在那里:) 然后是兼容性问题......在它无处不在之前还需要一段时间。

于 2009-01-21T20:11:41.263 回答
2

当您向服务器发送 HTTP 请求时,服务器设置的 cookie 也会由浏览器发送回服务器。服务器使用这些 cookie 来确定用户已登录等事实。

恶意攻击者可以利用这一点,在一些 JavaScript 的帮助下,可以在用户不知情的情况下窃取信息或在其他网站上执行未经授权的命令。

例如,可以要求用户访问具有以下 JavaScript 代码(假设为 jQuery)的站点:

<script type="text/javascript">
  $.post("http://some-bank.com/transfer-money.php", 
         { amount: "10000", to_account: "xxxx" })
</script>

现在,如果在执行上述代码时用户真的登录了银行,攻击者可能已经将 10K 美元转移到账户 XXX。

这种攻击称为跨站请求伪造(XSRF)。在Wikipedia上有更多关于此的信息。

这主要是由于这个原因,存在同源策略,浏览器不允许您在与源不同的域上执行 XMLHttpRequests。

有一些讨论实际上允许跨域 XHR,但我们必须看看这是否真的被接受。

于 2009-01-21T20:18:28.800 回答
1

正如您所提到的,这是一个令人担忧的问题,因为它可能被用于不良目的。它也可以很好地使用,因此,正在开发跨域协议。

最大的两个问题是当它与跨站点脚本 (XSS) 和跨站点请求伪造 (CSRF) 结合使用时。两者都是严重的威胁(这就是他们进入 OWASP 前 10 名和 SANS 25 名的原因)。

我可以看到它被滥用的唯一方法是,如果有人要注入 Javascript

这就是 XSS 太多的应用程序仍然容易受到攻击,如果浏览器安全模型不能阻止 X 域 AJAX,它们就会让用户面临相当大的攻击向量。

您可以简单地向文档添加 img、script 或 iframe 元素,以使其请求第三方 URL

是的,但是那些会发送一个 HTTP_REFERRER 并且(通过其他方式)可以被阻止以防止 CSRF。AJAX 调用可以更容易地欺骗标头,并允许使用其他方法绕过传统的 CSRF 保护。

于 2009-01-21T20:28:17.720 回答
1

我认为将其与普通 XSRF 攻击区分开来的另一件事是,您也可以通过 javascript 处理返回的数据。

于 2009-01-21T20:34:53.883 回答
1

不知道最大的问题是什么?将向其他域发送的 AJAX 调用首先发送到您的应用程序,然后使用过滤后的数据转发到其他地方,如果您确实需要解析返回的数据,并将其提供给用户。

处理敏感的 AJAX 请求?通过检查标头、存储会话时间数据或将传入的 IP 地址过滤到您信任的来源或您的应用程序来确定传入的傻瓜。

我个人希望将来看到的是,默认情况下,Web 服务器、框架和 CMS 上的所有传入请求都具有坚如磐石的安全性,然后明确定义将解析来自外部源的请求的资源。

于 2009-01-21T20:43:11.793 回答
1

有了<form>你可以发布数据,但你不能阅读它。有了XHR你,两者都可以。

类似页面http://bank.example.com/display_my_password对 XSRF(假设它只显示而不设置密码)和框架(它们具有同源策略)是安全的。然而,跨域 XHR 将是一个漏洞。

于 2009-01-21T20:59:48.063 回答
0

您将毫无戒心的访问者变成拒绝服务攻击者。

另外,想象一个窃取你所有 Facebook 内容的跨站点脚本。它打开一个 IFrame 并导航到 Facebook.com

您已经登录到 facebook (cookie),它会读取您的数据/朋友。并且做更多的坏事。

于 2009-01-21T20:09:31.720 回答