Ajax安全问题及可能的攻击

16

我正在开发的项目中,每个页面链接都使用 AJAX 调用,更具体地说,是 jQuery AJAX 调用。此外,除了登录以外,每个提交的表单也都是通过 AJAX 提交的,并且其中还包含一些 json 和 xml。我的问题是,这样做存在什么安全风险?所有服务器端代码都是 PHP 编写的,并且已经适当转义。


数据是使用 GET 还是 POST 发送的? - Tadeck
使用两个不同的加密密钥,每个请求都会更改。 - mcbeav
@zerkms 正确。但是,即使使用 bit.ly 链接,当您使用 GET、不使用引用检查并且不检查 AJAX 标头时,执行此类攻击也非常容易。这就是我所想的。但是,是的,您应该使用令牌等来对抗 CSRF。 - Tadeck
详细回答请访问 http://www.acunetix.com/websitesecurity/ajax/ - Jeffrey Nicholson Carré
您还可以在OWASP网站上找到一些指南:https://www.owasp.org/index.php/OWASP_AJAX_Security_Guidelines - Jeffrey Nicholson Carré
显示剩余4条评论
3个回答

13

AJAX中没有特定的内容。它只是您的浏览器执行的请求。它只是一般的HTTP请求,应该像其他任何HTTP请求一样得到保护,无论其XHR性质如何。


2
AJAX请求携带凭据,因此向Ajax开放服务可能会使它们面临XSRF的风险。 - Mike Samuel
5
@Mike Samuel: 嗯,什么?!Ajax请求并不比“正常”的请求更易受攻击,因为它们是相同的东西。顺便说一下,感谢你的负投票。期待你的证明。 - zerkms
1
@Mike Samuel:我知道CSRF是什么意思。但是ajax并不会使应用程序更容易受到攻击。即使是非ajax请求也存在CSRF漏洞。 "OP规定他们正确转义" --- 谁告诉你的?所有请求都应该以相同的方式处理,包括ajax和非ajax。因为它们没有攻击面。如果您无法安全地实现ajax方法(这意味着与其他方法相同),那就是您的问题。而我在哪里说我们不需要在所有请求中传递CSRF令牌了?请指出来。 - zerkms
1
@Mike Samuel:顺便问一下,你能证明你说的话吗?如果我给你一个链接,其中ajax请求与常规请求以相同的方式实现,你能利用任何漏洞吗?还是你只是一个除了引用甚至无法理解的页面之外什么都不会的家伙? - zerkms
1
@Mike,我认为@zerkms想说的是XHR请求并不比其他请求更不安全;它们都需要得到适当的处理。 - alex
显示剩余10条评论

2

被广泛认为,对于只通过GET方式公开数据并通过cookies授权用户的服务,使用XSRF令牌进行保护是不必要的。

但这并不是真的。当输出为JSON数组时,这些服务曾经存在AJAX特定的XSSI漏洞。

考虑一个名为/getfriends的服务,它返回像[ { "name": "Alice" }, { "name": "Bob" } ]这样的数据。

攻击页面可以执行以下操作:

 <script>
   var stolenData;
   var RealArray = Array;
   Array = function () {
     return stolenData = new RealArray();
   };
 </script>
 <script src="https://naivedomain.com/getfriends" type="text/javascript"></script>

第二个 <script> 标签通过用户的 cookies 跨域加载了 JSON 数据,由于 EcmaScript 3 中的一个怪异之处(在 EcmaScript 5.0 和现代 ES 3 解释器中已经修复),页面可以读取被盗数据,因为 JavaScript 解析器在解析 JSON 响应中的 [...] 时调用了被覆盖的 Array 构造函数。

通过 XSRF 令牌保护这些服务以及使用常规基于 cookie 的方法解决了该问题,禁止 GET,通过自定义头授权并包含解析断点也可以解决。解析断点的作用是使响应无效的 JSON,例如返回 throw 0; [{ "name": "Alice" }, { "name": "Bob" }],这样 XHR 客户端就可以去掉前缀 throw 0;,但通过 <script> 加载的客户端则无法去除。

最后,由于 JavaScript 解析器将加载的脚本解析为程序,因此只影响返回 JSON 数组的服务。返回 { "names": ["Alice", "Bob"] }/getfriend 服务不会有漏洞,因为该内容不是有效的程序,而是解析为带有无效标签的块。但是像 { names: [ "Alice", "Bob" ] } 这样的无效 JSON 是有漏洞的,因为它是有效的程序。


哦,太酷了,从来不知道这个,甚至不相信它会起作用 :-S - zerkms
@zerkms,允许此操作的规范语言在11.1.4数组初始化器中,其内容如下:“生产阵列文字:[Elisionopt]按以下方式进行评估: 1.将数组作为通过表达式new Array()创建新对象的结果”,但在EcmaScript 5中更改为“让数组成为通过表达式new Array()创建新对象的结果,其中'Array'是具有该名称的标准内置构造函数。” - Mike Samuel
@zerkms,请查看http://haacked.com/archive/2008/11/20/anatomy-of-a-subtle-json-vulnerability.aspx以获取更好的撰写说明。 - Mike Samuel
1
@random425,不行。你只想替换第一个而不是合法的出现,比如 do ... while(1);,所以也许可以用 response.replace(/^while \(1\);/, "") - Mike Samuel
非常感谢 @MikeSamuel! - random425
显示剩余6条评论

-1
Ajax违反了关于在POST数据中百分比转义保留字符的安全规则。简单来说,这允许对SQL模式进行恶意代码的直接注入,这些代码可以是以后从主机上检索和执行的PHP代码等。除非AJAX像正常浏览器处理表单一样对所有保留的GET和POST字符进行转义,否则在每次通信中对恶意代码片段进行完整扫描之前,不应该相信它。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接