为什么跨域Ajax是一个安全问题?

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

[编辑]

其中一些答案指出了以下几个原因,让我们指出他们不会造成拒绝的主要原因。

XSRF(Cross Site Request Forgery,也被称为CSRF,XSRF)

你可以做XSRF攻击而不用这个。 一般来说,XMLHTTPRequest根本就不被使用,仅仅是因为以与所有主stream浏览器兼容的方式创buildXMLHTTPRequest非常困难。 如果您希望它们加载您的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:你为什么要把漏洞留在一个新的特性中

你没有创造更多的不安全感。 你只是想方设法使用它的开发人员。 任何人想要使用这个function为邪恶(又名真棒)可以使用一些其他的方法来做到这一点。

结论

我把自己的回答为正确,因为他指出了这个关键问题。 由于XMLHTTPRequest允许您使用凭证(cookie)发送到目标站点,并读取从站点发回的数据,并发送人员凭据,因此您可以编排一些可提交一系列表单的JavaScript,包括确认表单,完成任何生成的随机密钥,以防止XSRF。 通过这种方式,您可以像银行一样浏览目标网站,而银行的networking服务器将无法分辨出提交所有这些表单的不仅仅是一个普通用户。

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

由于AJAX请求是(a)用用户凭证提交的,(b)允许调用者读取返回的数据。

这些因素的组合可能会导致漏洞。 有build议添加一个省略用户凭证的跨域AJAXforms。

您可以简单地将一个img,脚本或iframe元素添加到文档中

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

(除了故意设置允许的脚本之外,允许跨域脚本编写 – 或者某个人犯了可怕的混乱的脚本)。

你可以做XSS攻击而不用这个。 发布到第三方网站

这不是一个XSS攻击。 这是一个跨站请求伪造攻击(XSRF)。 有一些已知的解决XSRF攻击的方法,例如包括一次性或encryption的令牌,以validation提交是来自用户的故意而不是从攻击者代码发起的。

如果你允许跨域AJAX,你将失去这个保障。 攻击代码可以从银行网站请求一个页面,读取任何授权令牌,并在第二个AJAX请求中提交它们以执行转移。 这是一个跨站点脚本攻击。

POST的一个重要区别是:

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

而Ajax是在做任何POST之后,浏览器将会replace页面,并在完成Ajax调用之后 – 不是。 POST的结果是:

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

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

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

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

更好的解决scheme可能是允许通话本身,但不发送任何cookie。 这是非常简单的解决scheme,不需要任何广泛的开发。 在许多情况下,Ajax调用进入不受保护的位置,不发送cookie不会受到限制。

现在正在讨论的CORS(跨域资源共享),除其他外,都提到了发送/不发送cookie的问题。

好吧,显然你不是唯一那样感觉的人

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

编辑:从上面的search链接有一个有趣的讨论:

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

看起来像提案正在进行,以允许跨站点xmlhttp请求(IE 8,FF3等),但我希望他们一直在那里,当我为我的网站编写的代码:)然后有兼容性的问题…这将是无处不在的一段时间。

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

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

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

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

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

这种攻击称为跨站请求伪造(XSRF)。 关于维基百科的更多信息。

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

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

这是一个问题,因为它可以用于坏的目的,正如你所提到的。 它也可以用于良好的意图,因此,正在开发跨域协议。

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

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

这是XSS太多的应用程序仍然是脆弱的,如果浏览器安全模型不能阻止X领域的AJAX,他们正在打开他们的用户到一个相当大的攻击媒介。

您可以简单地将一个img,脚本或iframe元素添加到文档中,以便请求第三方URL

是的,但那些会发送HTTP_REFERRER和(通过其他手段)可以阻止,以防止CSRF。 AJAX调用可以更容易地欺骗头,并允许其他方法规避传统的CSRF保护。

我认为另外一件事情将XSRF与普通的XSRF攻击区分开来,就是你可以通过javascript来获取数据。

我不知道这个大问题是什么? 将AJAX调用发送到其他域名发送到您的应用程序,然后转发到其他地方与过滤的数据,parsing返回的数据,如果你真的需要,并饲料给用户。

处理敏感的AJAX请求? 通过检查标题,存储会话时间数据或将传入的IP地址过滤到您信任的来源或您的应用程序,来消灭传入的吸盘。

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

使用<form>您可以发布数据,但无法阅读。 用XHR你可以做到这一点。

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

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

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

您已经login到Facebook(cookie),它会读取您的数据/朋友。 而且做更多的坏事。