JSON 安全最佳实践?

Posted

技术标签:

【中文标题】JSON 安全最佳实践?【英文标题】:JSON security best practices? 【发布时间】:2010-09-28 13:52:07 【问题描述】:

在研究JSON vs XML 的问题时,我遇到了this question。现在,更喜欢 JSON 的原因之一被列为在 javascript 中易于转换,即使用 eval()。现在,从安全角度来看,这立即让我觉得可能存在问题。

所以我开始对 JSON 的安全性方面进行一些研究,并在这篇博客文章中了解 JSON is not as safe as people think it is 的安全性。这部分突出:

更新:如果您使用 JSON 100% 正确地,那么你将只有 顶层的对象。数组, 字符串、数字等都将是 包裹。 JSON 对象将失败 到 eval() 因为 JavaScript 口译员会认为它在看 块而不是对象。这 有很长的路要走,以防止 这些攻击,但它仍然是最好的 保护您的安全数据 不可预测的 URL。

好的,这是一个很好的开始规则:顶层的 JSON 对象应该始终是对象,而不是数组、数字或字符串。听起来对我来说是一个很好的规则。

对于 JSON 和 AJAX 相关的安全性,还有什么需要做或避免的吗?

上面引用的最后一部分提到了不可预测的 URL。有没有人有这方面的更多信息,特别是你如何在 php 中做到这一点?我在 Java 方面比 PHP 更有经验,在 Java 中这很容易(因为您可以将整个范围的 URL 映射到单个 servlet),而我所做的所有 PHP 都将单个 URL 映射到 PHP 脚本。

另外,您究竟如何使用不可预测的 URL 来提高安全性?

【问题讨论】:

我一点也不明白!当然,浏览器发出的任何请求(对任何 URL - 不可预测或不可预测)都可以使用控制台或一些花哨的 GM 脚本报告给用户...... “JSON 不像人们想象的那么安全”已经死了 【参考方案1】:

有许多针对 JSON 的安全攻击,尤其是 XSRF。

当 Web 服务使用 cookie 进行身份验证并使用包含敏感数据的 JSON 数组响应 GET 请求时,就会出现该漏洞。

如果攻击者可以诱骗登录到服务 naive-webapp.com 的用户访问他们的网站(或任何嵌入了他们控制的 IFRAME 的网站,例如通过嵌入式广告),那么他们可以插入 @987654323 @ 带有 SRC 的标签到 naive-webapp.com,并可能窃取用户的数据。 这取决于 JavaScript Array 构造函数的 JavaScript 怪癖,如下所示:

 <script>
   // Overload the Array constructor so we can intercept data
   var stolenArrays = [];
   var RealArray = Array;
   Array = function () 
     var arr = RealArray.apply(arguments);
     stolenArrays.push(arr);
     return arr;
   
 </script>
 <!-- even though the attacker can't access the cookies,
   - he can cause the browser to send them to naive-webapp.com -->
 <script src="//naive-webapp.com/..."></script>
 <script>
   // now stolenArrays contains any data from the parsed JSON
 </script>

EcmaScript 5 修复了导致 [] 在全局对象上查找 Array 的令人困惑的行为,并且许多现代浏览器不再容易受到这种攻击。

顺便说一句,Oil 对不可预测的 URL 的看法是错误的。 URL 中的加密安全随机标识符是保护资源的好方法。正如石油所说,基于身份的安全并不是万能的。 请参阅http://waterken.sourceforge.net/,了解基于 URL 中加密安全标识符的安全分布式应用方案示例,不需要身份概念。

编辑:

在考虑 JSON 与 XML 时,您还应该了解 XML 特定的攻击媒介。

XXE,XML 外部实体攻击,使用精心制作的 XML 通过防火墙访问文件系统和网络资源。

<!DOCTYPE root 
[
<!ENTITY foo SYSTEM "file:///c:/winnt/win.ini">
]>
...
<in>&foo;</in>

应用程序将输入(参数“in”,其中包含 win.ini 文件)嵌入到 Web 服务响应中。

【讨论】:

我明白了,所以如果 Web 服务器发送仅用于已登录用户的数据以响应 GET 请求,即使该数据是 JSON,也应该记住攻击者可以使用 或者仅仅依靠最外层是一个对象并且解析器因为 被解释为一个块而中断会有多安全? 如果您知道最外层始终是一个对象,并且您正确引用了属性名称,那么解析器应该会中断。【参考方案2】:

博客中的主要安全漏洞 (CSRF) 不是 JSON 特定的。改用 XML 就是一个大洞。事实上,完全没有异步调用同样糟糕。常规链接同样容易受到攻击。

当人们谈论独特的 URL 时,他们通常不是指 http://yourbank.com/json-api/your-name/big-long-key-unique-to-you/statement。相反,更常见的是使请求的其他内容独一无二。即 FORM 帖子中的值或 URL 参数。

通常这涉及在服务器端插入一个随机令牌到 FORM 中,然后在发出请求时进行检查。

数组/对象对我来说是新闻:

Script-Tags:攻击者可以嵌入一个 指向远程服务器的脚本标记 并且浏览器将有效地 eval() 给你的回复,但是它 丢弃响应,因为 JSON 是所有响应,您很安全。

在这种情况下,您的网站根本不需要使用 JSON 就容易受到攻击。但是,是的,如果攻击者可以将随机 html 插入您的网站,那您就完蛋了。

【讨论】:

【参考方案3】:

使用不可预测的 URL 来保护您的安全数据仍然是最好的

强调我的。胡说些什么! 最好通过一些适当的身份验证和可能的一些加密来保护您的安全数据。 JSON 交换仍然可以使用现有的身份验证技术(例如通过 cookie 的会话)和 SSL。

当您使用 JSON 将数据导出到匿名第三方(例如网络服务)。一个例子是谷歌的各种网络服务 API,其中匿名用户通过其他网站访问谷歌数据。他们使用域引荐来源网址和 API 密钥来确保允许中间人网站提供 Google 数据。

如果您只是使用 JSON 与直接的已知用户代理之间发送私人数据,请使用一些真正的身份验证和加密。如果您尝试提供网络服务,那么这真的取决于这些数据的“安全性”。如果它只是公共数据并且您不介意谁可以阅读它,那么我认为创建一个散列 URL 没有意义。


编辑:为了说明它们的含义,请考虑这一点。想象一下,您的银行提供了一个 JSON API 来获取报表。如果我可以输入http://yourbank.com/json-api/your-name/statement,你可能不会很高兴。

他们可以为您的帐户生成任何 JSON 请求中都需要的唯一字符串,例如:http://yourbank.com/json-api/your-name/big-long-key-unique-to-you/statement

我猜到的机会要小得多。但是您真的希望它成为您真正安全的数据和潜在的身份窃贼之间的唯一缓冲吗?没有。

【讨论】:

我认为您需要阅读博客的其余部分:他不主张除了不可预测的 URL 之外没有任何安全性。他说的是通过 cookie 实现的安全性还不够,他说明了原因。 身份验证没有帮助——这就是问题的重点。例如,如果用户登录到 target.com(即他们有一个会话 cookie),attacker.com 可能会尝试类似&lt;script type="text/javascript" src="http://target.com/secret-data-with-predictable-url.json"/&gt; 并使用 Mike 描述的数组构造函数技巧来获取数据,如果顶部 - level 元素是一个数组。 两个问题——你混淆了身份验证和授权,然后你错误地认为密码不太容易被猜到。哪个更容易猜到:随机生成的标识符通常具有 128 位到 1024 位的熵,还是人工生成的密码平均具有 18 位条目? URL 的主要问题是用户不习惯将 URL 保密,并且必须做一些工作来防止通过引荐来源网址等泄露。 Waterken 试图解决这两个问题。

以上是关于JSON 安全最佳实践?的主要内容,如果未能解决你的问题,请参考以下文章

21条最佳实践,全面保障 GitHub 使用安全

JSON 验证是最佳实践吗? [关闭]

保护REST API/Web服务的最佳实践

JSON 数据结构 - JSON 到对象 - 最佳实践

PostgreSQL安全最佳实践

在 JSON 中传递美元金额的最佳实践是啥?