NoSQL注入的分析和缓解(2)
在MongoDB中,查询和数据以JSON格式描述,这在安全方面要优于SQL,因为它是更充分定义的,容易进行加密和解密,而且在每种编程语言中都有不错的原生实现.像SQL注入那样对查询结构的破坏,在JSON结构的查询中会更难实现.在MongoDB中常见的插入语句应该是这样的: 这会插入一个新的文档到books的集合中,它具有title(标题)和author(作者)字段.常见的查询条件应该是这样的: 除限制要查询的字段之外,查询中还可以包括正则表达式和条件. PHP重言式注入让我们审视一下图3中所画的架构,一个使用PHP实现后端的Web应用,它将用于查询数据存储的请求编码为JSON格式.让我们使用一个MongoDB示例去演示数组注入漏洞吧,从技术和结果上来看这是一个与SQL注入有些类似的攻击手段. 图3 使用MongoDB的.一个使用PHP实现后端的Web应用,它把用于查询数据存储的请求编码为JSON格式. PHP编码数组为原生JSON.嗯,数组示例如下: 将由PHP编码为以下JSON格式: 果一个PHP具有登录机制,由用户浏览器通过HTTP POST(它像HTTP GET一样容易受到攻击)发送过来用户和密码,常见的POST URL编码应该是这样的: 后端PHP代码针对该用户对它进行处理并查询MongoDB,如下所示: 这本身合情合理没什么问题,直觉上开发人员可能喜欢用以下查询: 然而,PHP针对关联数组有个内置的机制,这让攻击者有机可乘,可发送以下恶意的数据: PHP会把该输入解析为: 它会编码为如下MongoDB查询: 因为$ne是MongoDB用来判定条件是否不相等的,所以它会查询登录集合中的所有用户名称不等于1且密码也不等于1的记录.因此,本次查询将返回登录集合中的所有用户.换成SQL的表述法,就等同于以下查询语句: 在这种情况下,漏洞就为攻击者提供了一个不必有效凭证即可登录应用的方式.在其他变体中,该漏洞可能会导致非法数据访问或由无特权的用户执行特权操作.为缓解这个问题,我们需要转换从需求中接收的参数为适当类型,在本例中,可使用字符串,如下所示: NoSQL联合查询注入SQL注入漏洞经常是由于未对用户输入进行适当编码而直接拼接查询造成的.在MongoDB之类的流行数据存储中,JSON查询结构使攻击变得更难了.然而,这并不代表不可能. 让我们看一个通过HTTP POST发送用户名和密码参数到后端的登录表单,它通过拼接字符串的方式得到查询语句.例如,开发人员可能会这么做: 具有有效输入时,得到的查询语句是应该这样的: 但具有恶意输入时,这个查询语句会被转换为忽略密码的,在无需密码的情况下登录用户账号.恶意输入示例如下: 该输入会被构建到该查询中: 只要用户名是正确的,这个查询就可以成功.转换成SQL的表述,这个查询类似于以下语句: 密码成为这个查询多余的一部分,因为()内的条件总为真,所以不会影响到查询的最终结果. 这是怎么发生的呢?以下为拼接出的查询串,用户输入为加粗字体,剩余的文本串为无格式字体: 这个攻击在任何只要用户名正确的情况下都将成功,一般得到个用户名并不是什么难事. NoSQL JavaScript注入NoSQL数据库中有个共同特性,那就是可以在数据库引擎中运行JavaScript,从而可以执行复杂的查询或MapReduce之类的事务.包括MongoDB 和 CouchDB及其后续的 Cloudant 和 BigCouch等流行的数据库都允许这么做. 如果不干净的用户输入发现这种查询方式的话,这么执行JavaScript就等于把薄弱面暴露给攻击者了. (编辑:ASP站长网) |