NoSQL注入漏洞与防护
字数 859 2025-11-15 21:09:38
NoSQL注入漏洞与防护
描述
NoSQL注入是一种针对非关系型数据库(如MongoDB、Redis、Cassandra)的安全漏洞,攻击者通过操纵输入数据(如查询参数、JSON负载)来破坏数据库查询逻辑,可能导致数据泄露、越权访问或数据篡改。与SQL注入不同,NoSQL注入利用的是应用程序对用户输入的不安全处理方式,例如直接将用户输入拼接到查询语句中,或错误使用运算符(如$ne、$gt)。
解题过程
-
漏洞原理
- NoSQL数据库使用JSON/BSON格式的查询语言(如MongoDB的
find({age: {$gt: 18}})),若应用程序未对用户输入进行过滤或类型检查,攻击者可注入操作符。 - 示例场景:登录功能中,代码直接将用户输入的
username和password拼接到查询:
攻击者输入db.users.findOne({username: req.body.username, password: req.body.password});username=admin&password[$ne]=123,查询变为:
此时只要{username: "admin", password: {$ne: "123"}}password不是"123"即返回用户数据,导致绕过认证。
- NoSQL数据库使用JSON/BSON格式的查询语言(如MongoDB的
-
漏洞检测方法
- 输入运算符:在参数中尝试注入NoSQL操作符(如
$eq、$ne、$regex)。 - 类型混淆:提交数组或对象(如
{"password": {"$gt": ""}})触发查询逻辑错误。 - 工具辅助:使用Burp Suite扩展(如
NoSQLi)或手动修改Content-Type为application/json测试JSON负载。
- 输入运算符:在参数中尝试注入NoSQL操作符(如
-
防护措施
- 输入验证:严格校验输入类型和格式(如预期字符串则拒绝对象/数组)。
- 参数化查询:使用ORM/ODM(如Mongoose)的安全方法,避免拼接查询。
- 白名单过滤:禁止查询中使用用户可控的操作符(如清理输入中的
$符号)。 - 最小权限原则:数据库连接账户仅具备必要权限,限制查询范围。
-
实战案例
- MongoDB注入防护:
// 错误示例:直接拼接输入 db.users.find({username: userInput}); // 正确示例:使用转义或限制类型 const username = String(userInput); // 强制类型转换 db.users.find({username: username}); - 登录逻辑修复:采用哈希比对而非直接查询密码:
const user = await db.users.findOne({username: validatedUsername}); if (user && bcrypt.compare(password, user.hashedPassword)) { // 登录成功 }
- MongoDB注入防护:
通过结合输入验证、安全查询API和密码学安全实践,可有效防御NoSQL注入。