本文发表在IEEE COMPSAC2020,作者是来自孟加拉工程技术大学的研究团队。通讯作者是Rifat Shahriyar,是孟加拉工程技术大学的Associate Professor ,主要研究方向是blockchain,web和机器学习:

项目开源地址:https://github.com/anonymous1363101/nosql-injection-detection
主要内容
NoSQL注入漏洞第一次由Diaspora在2010年发现,随后,Sullivan演示了基于Java脚本查询的MongoDB代码注入攻击。2015年一个篇文章表明,40,000左右的Web应用程序因为使用了MongoDB而遭受了注入攻击。但是此前关于NoSQL注入检测的工具和学术研究比较少,Sqreen是一款NoSQL注入检测工具,但是仅支持检测两种类型的注入攻击,PHP数组注入攻击和OR注入攻击。所以作者利用7种监督式分类器,对4种不同的NoSQL注入进行了检测。本篇论文的主要Contribution为:
- 手动生成了要给包含良性和恶意的MongoDB和CouchDB查询语句数据集,一共1345个NoSQL查询语句,其中75%为良性查询,并且对该数据集在一个vulnerable的服务器上进行了测试;
- 设计了19个特征来分类良性查询和注入查询,虽然训练样本比较少,但是最后取得效果不错;
- 证明了监督学习模型可以有效地解决NoSQL检测问题;
- 生成了可用的工具。
NoSQL注入攻击
本文主要关注四种NoSQL注入攻击方式:
- PHP array Injection

1 | db.logins.find({ username: { $ne: 1 }, password: { $ne: 1 } }) |
该查询会返回username和password不为1的查询结果。
- OR Injection

在MongoDB的查询语法中,{}会永远返回true,所以上面的查询会返回用户名为tolkien的用户数据,只需要提供正确的username就可以成功注入。
- JavaScript Injection

- Piggy-Backed Query

设计与实现
在本篇论文中,作者使用基于特征的监督学习分类器来检测NoSQL注入。具体的实验步骤如下图所示:

1. Training Dataset Generation
为了训练分类器,所以还需要可靠数据集的支持,但是目前并没有公开的可用的关于NoSQL注入相关的学习集。
数据集分为benign queries和injection queries,前者来自MongoDB和CouchDB的官方链接:

injection queries主要来自一些比较知名的安全网站,博客或是一些state-of-the-art工作:

然后,在现有数据集上,通过交叉(合并两个查询的部分)和突变(调整query中的一个元素)来增强数据集,手动生成大量良性查询和注入查询数据集。接着搭建存在漏洞的web站点,后端数据库为MongoDB,进行实验测试,并且对CouchDB数据库也进行一次相同的实验。最后的实验数据集为:
- 1004 MongoDB查询语句,包括203条恶意的注入查询语句;
- 350 CouchDB查询语句,包括50条恶意的注入查询语句。

这些数据集包括前面提到的4种NoSQL注入方式,但是其中OR Injection的payload特别少,原因是OR Injection相对其他三种方式的变种比较少。
下图是injection queries的数据集样例:

2. Feature Design
然后是设计需要从数据集中提取的信息特征,作者设计了19种特征,然后从中选取了信息增益和相关性最高的10种特征。值得注意的是,任何单个特征都不会单独决定分类结果,而是与其他特征相结合,它们共同决定了分类器的加权结果。
这19种特征有:
Contains Empty String,许多的NoSQL注入字符串都包含空字符串如
{},在MongoDB中该查询永远返回true;Contains Injection Payload,包含一些常见的NoSQL注入Payload,这些Payload可以从github或是网上寻找;
Contains Not Equal,包含在PHP array Injection中常见的
$ne;Contains Comparison,包含一些比较用的关键字,如
find(),find.sort(),$eq,$gt,$gte,$lt,$lte,$ne等,在benign数据集中也很常见;Contains Logical Operator,包含一些逻辑操作,如
$or,$and,$not和$nor等关键字;Contains Evaluation Query Operation,比如
$where,$mod,$regex等命令;Presence of _;return, return true, and return 1_,发表在CCS13的Diglossia表明一些注入语句中会包含一些return语句,其中三种被认为是恶意的语句:
;return,return true和return 1;New Query,比如原始的query只进行一次查询,但是注入的语句中包含新的query,就说明非常有可能是恶意的;
Always True Expression,
/./,/.*/等在正则表达式中表示匹配任何字符串,当它们被用作注入时,对于数据库中的每个条目,查询将变为true,所以很可能是恶意的注入攻击;Contains Element Query Operations,MongoDB的元素查询操作,在注入中常用的关键字,如
$exists和$type;Null comparison,许多的NoSQL注入中会包含null字符串,如果null出现在query中,很有可能是将一些数据和null进行比较,得到的结果很有可能是true,比如:
1
login.php?username[$ne]=null&password[$ne]=null
对应的PHP array injection为:
1
2
3
4$collection->find(array(
"username" => array("$ne" => null),
"password" => array("$ne" => null)
));Targets Table,
createTable()和showTable()命令可以分别创建新表或显示当前表,这两者都可以作为恶意命令来创建访问点或获取隐私数据;Alters Collection,命令直接影响数据库,这些通常不允许通过用户输入或来自REST API的输入执行;
Drop Database,
dropDtabase()命令能删除数据库,所以在用户输入中是很危险的;Update query,
$update和$save命令可以更新数据库条目;Remove query,攻击者可以用
$remove命令从数据库中移动数据;Limit keyword,
Limit关键字用于限制对所有数据条目的访问,但是攻击者可以利用它来访问的更多的数据Infifinite Loop,
while(true)语句可以导致服务器受到DoS攻击;Contains _;}//_,JavaScript Injection中可能会出现。
3. Feature Selection
这一步的目的是从19个特征中挑选出10个特征。作者使用WEKA’s ClassifierSubsetEval with J48(decision tree),IBK(k nearest neighbor) classifier,greedy step-wise search with backward elimination,根据信息增益和相关度最高的10种特征。
结果如下图所示:

作者选择这10个特征来提高分类器的性能,发现减少特征的维度在accuracy、precision,recall和Fβ(β=2)方面都有显著的提高。
实验评估
为了选取效果更好的监督式分类器,作者使用了以下几种分类器:
- decision tree based ID3 algorithm
- neural network with back-propagation
- random forest
- AdaBoost
- k nearest neighbor
- XGBoost
- SVM
然后使用10-fold交叉验证,对这10份数据集轮流进行一次10-fold交叉验证。最后的结果取平均值。
而且考虑到数据集的benign queries和malignant queries的分布不均,3.95:1(MongoDB)和6:1(CouchDB),所以对其进行过采样将其比例调整为1.13:1(MongoDB)和1.1:1(CouchDB)。
作者对7个分类器进行了实验,调整了它们的超参数,以获得更好的训练模型,下表11中给出了每个分类器的最优参数:

最后分类器的分类结果如下图所示:

从结果可以知道,无论后端数据库是MongoDB还是CouchDB,neural network的分类效果都是最好的。
部署策略
本文的工具将在server上作为插件来检测NoSQL注入。先将用户的请求拦截下来,转发到工具所在的端口,比如MongoDB的端口是100,工具的端口是101,先将向MongoDB的query转发到101端口。
工作原理如下图所示:

与Sqreen的对比
作者将本文的工具和另一NoSQL检测工具Sqreen进行了对比,主要从三方面进行:
- 检测到的危险行为数量:

- Sqreen只能支持基于Ruby和Node.js的服务器,而本文的工具不会受到平台的限制。
- Sqreen支持检测两种类型的NoSQL注入,PHP数据注入攻击和OR注入,本文的工具支持四种NoSQL注入攻击。
总体评价
本文采用监督式学习来检测可以的NoSQL查询,实验最后的检测效果还不错,但实验的数据集个人认为还不够丰富,尤其是CouchDB数据集,相比MongoDB数据集少了很多,而且最后的训练效果也可以看到是差了一点。