JSON安全最佳做法?


77

在研究JSON与XML的问题时,我遇到了这个问题。现在,首选JSON的原因之一是Javascript易于转换,即使用eval()。从安全角度来看,这立即使我感到潜在的问题。

因此,我开始对JSON的安全性方面进行研究,并在此博客文章中就JSON的安全性不如人们认为的那样进行了研究。这部分突出:

更新:如果您正确地执行JSON 100%,那么您只会在顶层拥有对象。数组,字符串,数字等都将被包装。然后,JSON对象将无法执行eval(),因为JavaScript解释器会认为它正在查看的是块而不是对象。这对于防止这些攻击有很长的路要走,但是仍然最好使用不可预测的URL保护您的安全数据。

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

关于JSON和AJAX相关的安全性,还有其他事情要做或避免吗?

以上引用的最后一部分提到了不可预测的URL。是否有人对此有更多信息,特别是您如何使用PHP?与Java相比,我在Java方面的经验要丰富得多,并且在Java中这很容易(因为您可以将整个URL映射到单个servlet),而我所做的所有PHP都将单个URL映射到了PHP脚本。

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


我一点都不明白!当然,使用控制台或一些通用的GM脚本,浏览器发出的任何请求(对任何URL的请求-不可预测或不可预测的)都可以报告给用户...
James

“ JSON的安全性不如人们认为的安全”
Stephan Dollberg

Answers:


19

博客(CSRF)的主要安全漏洞不是特定于JSON的。相反,使用XML就像是一个大漏洞。确实,根本没有异步调用也很糟糕。常规链接同样容易受到攻击。

当人们谈论唯一的URL时,它们通常不是指http://yourbank.com/json-api/your-name/big-long-key-unique-to-you/statement。取而代之的是,使请求的其他特征变得唯一是更常见的。即FORM帖子中的值或URL参数。

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

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

脚本标签:攻击者可以嵌入一个指向远程服务器的脚本标签,浏览器将为您有效地eval()答复,但是它丢弃了响应,并且由于JSON都是响应,因此您很安全。

在这种情况下,您的站点完全不需要使用JSON即可受到攻击。但是,是的,如果攻击者可以将随机HTML插入您的网站,那么您就敬酒了。


55

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

当Web服务使用Cookie进行身份验证并响应包含GET请求的敏感数据的JSON数组时,将发生此漏洞。

如果攻击者可以诱骗登录服务naive-webapp.com的用户访问其网站(或例如通过嵌入式广告嵌入其控制的IFRAME的任何网站),则他们可以插入<script>带有SRC的标签, naive-webapp.com,并可能窃取用户的数据。这取决于具有JavaScriptArray构造函数的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中的加密安全随机标识符是保护资源的一种好方法。正如Oil所说,基于身份的安全性不是万能药。有关基于URL中不需要身份概念的加密安全标识符的安全分布式应用程序示例,请参见http://waterken.sourceforge.net/

编辑:

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

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

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

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


我知道了,因此,如果Web服务器正在发送仅用于登录用户的数据以响应GET请求,即使该数据是JSON,也应牢记,攻击者可以使用<脚本>标签。那么解决方案是什么?您的网络应用应注意不要发送任何可能被解析为Javascript甚至JSON的内容,以响应GET请求。它应该仅用于POST(可能具有与服务器设置的cookie匹配的令牌)。我认为这是针对其他一些威胁的类似解决方案,不是吗,例如GIFAR?
thomasrutter 2010年

1
还是仅仅依靠最外层作为对象,并且因为{}被解释为一个块而使解析器中断,将有多安全?
thomasrutter 2010年

如果您知道最外层始终是一个对象,并且正确地引用了属性名称,则解析器应该会中断。
Mike Samuel

3

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

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

仅当您使用JSON将数据导出到匿名第三方(例如,Web服务)时,依靠某人不猜测URL(他们实际上是在谈论什么)才是一种合理的技术(即使如此,也只是这样)。 。一个示例是Google的各种网络服务API,匿名用户可以通过其他网站访问Google数据。他们使用域引荐来源网址和API密钥来确保允许该中间人网站提供Gooogle数据。

如果您仅使用JSON与直接的已知用户代理之间来回发送私有数据,请使用一些真实的身份验证和加密。如果您要提供Web服务,则实际上取决于此数据的“安全性”。如果这只是公共数据,而您不介意谁可以读取,则我看不出要创建一个错误的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

我猜出来的机会要少得多。但是,您真的希望它是真正安全的数据和潜在的身份盗窃者之间的唯一缓冲区吗?没有。


2
我认为您需要阅读博客的其余部分:除了不可预测的URL之外,他不主张任何安全性。他说的是,通过cookie的安全性还不够,他证明了原因。
cletus

4
身份验证无济于事-这就是问题所在。例如,如果用户登录到target.com(即,他们有一个会话cookie)<script type="text/javascript" src="http://target.com/secret-data-with-predictable-url.json"/>,那么如果顶级元素为,则Attacker.com可能会尝试类似的操作并使用Mike描述的Array构造函数来获取数据。数组。
乔·利斯

2
两个问题-您将身份验证与授权相混淆,然后错误地认为密码不容易被猜中。哪个更容易猜测:随机生成的标识符通常具有128位至1024位之间的熵,还是人为生成的密码平均具有18位输入?URL的主要问题是用户不习惯于保守URL的秘密,必须做一些工作以防止通过引荐来源网址等泄漏。Waterken试图解决这两个问题。
Mike Samuel
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.