JSON 和 XML 都用作服务器客户端通信的媒介。那么,为什么一个安全问题而不是另一个呢?
根本区别在于,顾名思义,JSON(JavaScript 对象表示法)与 JavaScript 非常接近和亲爱,因此在设计一些 JavaScript 方法和功能时,JavaScript 将 JSON 字符串视为一杯茶并尝试直接解释它,这给出了攻击者的变通方法是欺骗 JavaScript 解释器以运行嵌入在字符串中的恶意 JavaScript,从而导致漏洞,而 XML 必须经过解析阶段才能被解析为对象,从而使其更难攻击。2 个这样的 JavaScript 功能是 eval() 方法和标记。
这些如何造成安全漏洞?
虽然 web 遵循同源策略,但历史上也发现了绕过它的漏洞,恶意网站利用它们向经过身份验证的用户网站发送跨站点请求,破坏了同源策略的意图。
示例:尽管有同源策略,但 web 允许一些标签,如<img> <script>
发出跨源 GET 请求。
假设您在一个网站上www.authenticatedwebsite.com
,但被引诱打开一个www.malicious.com
在其 html 中包含标签的
网站<script src="www.authenticatedwebsite.com/get-user-order-history" />
攻击者www.malicious.com
使用此脚本标记行为从 www.authenticatedwebsite.com
.
现在,调用 src url 的脚本标签如何将 url 响应存储到 javascript 对象[以执行将其发布到恶意站点服务器等操作]?
JSON和 XML 的作用在这里被证明是更安全的。由于 JavaScript 可以很好地理解 JSON,一些 JavaScript 解释器将裸 JSON 字符串解释为有效的 JavaScript 并运行它。
运行 JSON 字符串可能会做什么,因为它仍未分配给变量?
这可以通过另一个花哨的 hack 来实现。如果返回的 JSON 字符串表示一个数组。JavaScript 将尝试运行 Array 类的构造函数。现在可以在 JavaScript 中重写 Array 的构造函数了。您可以执行以下操作:
Array = function(){ yourObject = this };
这基本上是覆盖 JavaScript 数组构造函数,这样每当 JavaScript 调用构造函数时,当前解释的数组就会分配给 yourObject,从而使恶意网站可以访问您的私有数据。
现在,这种攻击可以与 JSON 字符串的变体一起使用,并具有更复杂的黑客攻击。
尽管上面代表了一个有效的场景,其中 JSON 作为 GET API 的返回格式可能很危险。这实际上仅在某些浏览器的某些版本中是可能的,据我所知,所有现代版本的著名浏览器都已缓解它,但是由于您的用户群可以跨浏览器版本划分,因此您需要小心 GET API以裸 JSON 格式提供私人信息。
用来规避这种情况的一种技术是在 JSON 响应字符串前面添加一个 while(true),这将永远不允许 JavaScript 解释器访问实际的字符串。但它会在您的客户端产生解析开销。
JSON 可能导致的另一个可能的事故eval()
是在浏览器客户端使用方法来解析 JSON。由于eval()
具有运行脚本的能力,如果您的 JSON 字符串包含一些隐藏的脚本,这些脚本eval()
运行并执行攻击者注入的脚本要求它执行的危险操作,则可能证明您的系统存在安全问题。eval()
但正如其他人所提到的,通过在客户端代码中的任何地方严格放弃作为 JSON 解析器的方法,可以轻松防止这种攻击。此漏洞插件对于存储用户生成内容的网站非常重要。