注入NoSql

注入NoSql

术语NoSQL用于指各种不同于标准的关系数据库体系架构的数据存储区。NoSQL数据存储区呈现使用键/值映射的数据,并且不依赖于固定的方案,如传统的数据库表。键和值可以任意定义,而且值的格式通常与数据存储区无关。键/值存储的另一个特点在于,值可能为数据结构本身,因而可以实现层次化存储,这与数据库方案中的平面数据结构不同。

支持上述数据存储的NoSQL具有各方面的优势,这些优势主要体现在处理庞大的数据集方面,以便于根据需要对数据存储区中的层次化数据进行优化,以减少检索数据集的开销。在这些情况下,传统的数据库可能需要对表进行复杂的交叉引用,才能代表应用程序检索信息。

从Web应用程序安全的角度看,我们主要关注应用程序如何查询数据,因为这决定了攻击者可以进行何种形式的注入。就SQL注入而言,不同数据库产品采用的SQL语言答题相似。相反,NoSQL代表着一类全新的数据存储区,它们的行为各不相同。而且,它们并非全部使用单一的查询语言。

以下是NoSQL数据存储区采用的一些常用的查询方法:

  • 键/值查询
  • XPath
  • 编程语言

NoSQL是一种快速发展的相对较新的技术。与SQL等比较成熟的技术不同,它并没有进行大规模部署。因此,对于NoSQL相关漏洞的研究仍处于早期阶段。此外,由于许多NoSQL技术访问数据的方式十分简单,讨论注入NoSQL数据存储区的示例有时候明显是虚构的。

几乎可以肯定的是,当前和将来的Web应用程序使用NoSQL数据存储区的方式将存在可被利用的漏洞。

注入MongoDB

许多NoSQL数据库利用现有的编程语言来提供灵活、可编程的查询机制。如果使用字符串连接构建查询,攻击者就可以尝试破坏数据并更改查询的语法。以下面的查询为例,它基于MongoDB数据存储区中的用户记录进行登录:

1
2
3
4
5
6
7
8
9
10
$m = new Mongo();
$db = $m->cmsdb;
$collection = $db -> user;
$js = "function() {return this.username = '$username' & this.password = '$password';}";
$obj = $collection->findone(array('where' => $js));
if (isset($obj["uid"])) {
$logged_in = 1;
} else {
$logged_in = 0;
}

$js是一个JavaScript函数,其代码是动态构建的,并且包含用户提交的用户名和密码。攻击者可以通过提供以下用户名和任意密码来避开验证逻辑:

Marcus’//

生成的JavaScript函数如下所示:

1
function() {return this.username = 'marcus'//' & this.password = 'aaa';}

在JavaScript中,双正斜杠(//)表示行尾注释,因此,函数中的剩余代码将被注释掉。另一种不使用注释而确保$js函数始终返回为“真”的方法,是提供以下用户名:

a’ || 1 == 1 || ‘a’ == ‘a

JavaScript以如下方式解释各种运算符:

(this.username = ‘a’ || 1 == 1) || (‘a’ == ‘a’ & this.password == ‘aaa’);

这将匹配用户集合中的所有资源,因为第一个选择性条件始终为真(1始终等于1)。

0%