{“$ne”:”2026″}:我在某AI平台的登录框里贴了个操作符,变成了任意用户的“影子”

admin 2026-08-08 05:18:11 网络安全文章 来源:ZONE.CI 全球网 0 阅读模式

文章总结: 本文演示了2026年针对MongoDB的NoSQL注入攻击,通过利用API版本差异和操作符如ne、regex绕过类型校验,从登录框逐步窃取全量用户数据。文章强调大模型应用对MongoDB的依赖导致此类漏洞重现,并提供了防御建议如类型校验、最小权限和AI赋能WAF。核心结论是NoSQL注入未消失,接口设计缝隙是漏洞根源。 综合评分: 85 文章分类: 渗透测试,漏洞分析,WEB安全,红队,安全建设


cover_image

{“$ne”:”2026″}:我在某AI平台的登录框里贴了个操作符,变成了任意用户的“影子”

原创

逍遥 逍遥

昆仑AI安全实验室

2026年7月26日 00:56 广东

在小说阅读器读本章

去阅读

大模型创业潮下,MongoDB 成了香饽饽。向量数据库太贵,PostgreSQL 插个 pgvector 又差点意思,于是大量中小 AI 团队不约而同地选择了 MongoDB——存用户 Prompt,存对话历史,顺便存一下用户密码的哈希。但他们忘了一件事:把 MongoDB 直接暴露给前端的后果,就是 NoSQL 注入。

这不是 2012 年的老皇历。2026 年的 NoSQL 注入已经学会了“隐身”,它能把请求伪装成完全合法的 JSON 结构,能在 AI 驱动的 WAF 眼皮底下把人偷成管理员。今天拿一个真实授权的 AI 对话平台开刀,演示一遍从登录框到全量用户数据窃取的全过程。

一、先忘掉 SQL,记住“操作符”

MongoDB 的查询语法是 JSON 对象。后端处理登录时,往往是把前端传过来的用户名和密码拼进一个 findOne 查询:

db.users.findOne({"username": username, "password": password})

如果后端没有做类型校验,直接把前端传来的 JSON 对象作为值传入,攻击者就能利用 MongoDB 的查询操作符劫持查询逻辑。最经典的 payload 是把密码从字符串替换为 {"$ne": ""}

{  "username": "admin",  "password": {"$ne": ""}}

这会让查询变成:“找到一个用户名为 admin,且密码不等于空字符串的用户”。只要 admin 的密码不是空,查询就返回真,攻击者直接以 admin 身份登录。这个技巧够老,但它一夜间成了大模型 Prompt 工程师的噩梦——因为他们根本不知道 JSON 里还能塞对象。

二、2026年的新防御和新绕过

老一套的 $ne 注入,现在稍微正规一点的后端都会做类型校验:if (typeof password !== 'string') return error。但在微服务和高并发场景下,数据往往要经过好几层过滤。我们的突破口就在于:如何让请求看起来从头到尾都是合法的字符串,却在到达 Mongo 驱动时变成对象。

这里用到了 2026 年新出现的一种手法——利用 REST API 的批量操作语法糖。很多为了兼容 OpenAI API 接口的对话平台,后端接受类似 Chat Completions 的请求格式,并允许在 user 字段里传一个 JSON 字符串,后端会 JSON.parse 这个字符串。如果解析出来的结果是对象,后端在存入日志或做其他操作时,可能不小心把它作为查询条件的一部分。

更直接的场景是:平台提供了一个“根据用户画像批量查询”的 GraphQL 接口,变量类型允许传入 JSON 标量。攻击者就可以把 $ne 包装在 JSON 字符串里,绕过前端字符类型的 WAF 检查,待 GraphQL 引擎解析后,对象被原样塞进 Mongo 查询。

我在这次测试中用的是另一种巧劲:利用 API 版本差异。平台同时提供了 v1 和 v2 两个登录接口,v2 做了严格的类型检查,但 v1 因为历史兼容问题,仍然接受 application/x-www-form-urlencoded 格式的请求。而 urlencoded 格式在解析 password 参数时,默认不区分数值和字符串,传 password[$ne]= 就能构造出一个包含操作符的子对象。WAF 只盯着 v2 的 JSON Body,v1 的老接口根本没人看。我就是在 v1 上用最原始的 $ne 直接越过了防线。

三、实战:从登录框到全量数据,只花了三步

第一步:侦察接口历史

打开目标 AI 对话平台的登录页,查看网页源码,发现 JS 里引用了 api/v1/login 和 api/v2/login 两个端点。v2 的请求体是 JSON,v1 的请求体是 Form Data。在 Burp 里试了 v2 传 {"password": {"$ne":""}},返回 400 Bad Request: password must be string。转战 v1:

POST /api/v1/login HTTP/1.1Content-Type: application/x-www-form-urlencoded
[email protected]&password[$ne]=

响应返回了 200 OK,并且 Set-Cookie 里带着一个有效的 session_token。此时我已经以管理员身份登录。

第二步:读取敏感信息

登录后,我访问了个人信息接口 /api/v1/user/profile,响应体里除了用户名、邮箱,还意外地返回了一个 openai_api_key 字段。原来是平台为了方便用户使用自己的 API Key 来调用模型,把 Key 存成了明文。我立刻意识到这个漏洞的严重性:每拿到一个用户,就能白嫖他的 OpenAI 额度,甚至能看到他所有的历史对话。

第三步:使用 $regex 盲注全量用户

有了管理员 cookie,我尝试访问用户列表接口 /api/v1/admin/users,但提示权限不足——这个 admin 账号只是普通管理员,不是超级管理员。于是我开始用 NoSQL 注入做数据提取。在搜索用户的接口 /api/v1/users/search?username= 上,后端是这么写的:

db.users.find({"username": {"$regex": req.query.username}})

因为没有做参数过滤,我可以传入操作符。我构造了一系列请求,用 $regex 配合 ^ 锚点逐字符盲注超级管理员的邮箱:

/api/v1/users/search?username[$regex]=^a/api/v1/users/search?username[$regex]=^ad/api/v1/users/search?username[$regex]=^adm...

当返回的用户列表里出现了一个 role: "superadmin" 的条目,我就知道邮箱的前缀已经对了。继续尝试,最终拿到了完整的邮箱地址。接着用同样的 $regex 盲注他的重置密码令牌,然后用这个令牌重置了超级管理员的密码,登入后台,导出了全量用户的对话记录和 API Key。

四、不止 $ne:2026年 NoSQL 注入的“全家桶”

在后续的排查中,我发现这个平台暴露的攻击面远不止登录框。

  • $where 注入:某个统计接口允许管理员传一个 JavaScript 函数作为过滤条件,后端直接 eval 了这个函数。注入 sleep(5000) 直接造成拒绝服务。
  • 聚合管道注入:一个报表接口接受用户传入的 $lookup 管道阶段,我利用它关联了财务表,拿到了平台的分成数据。
  • 时间型盲注:当 $regex 被 WAF 检测到正则字符时,我用 $function(MongoDB 4.4+ 的新操作符)定义了一个自定义函数,在其中执行 sleep(2000),根据响应时间判断字符是否正确,这已经摸到了时序盲注的天花板。

五、防御:不只是过滤关键字

  • 禁止客户端传入操作符:使用 mongo-sanitize 或 express-mongo-sanitize 等中间件,直接移除请求体中的 $ 和 . 开头的键。
  • 类型严格校验:对密码等字段,后端必须断言其为 string 类型,不是就拒绝。
  • 最小权限原则:数据库账号按功能分配权限,登录查询用只读账户,且只能访问 users 集合的必要字段。
  • 下线和监控老旧 API:定期扫描线上接口,像 v1 这种历史遗留的未加固端点,应该尽快下线或纳入 WAF 监控范围。
  • AI 赋能防御:2026 年,已经有 WAF 开始用大模型分析请求的“业务意图”。如果一个本该是字符串的字段变成了深度嵌套的对象,即使它没有命中规则,AI 也能根据上下文判断风险。

六、结语

NoSQL 注入在 2026 年并没有消失,反而因为大模型应用对 MongoDB 的偏爱而找到了新的温床。攻击者不需要 0day,只需要在成千上万个 API 里找到那个还在接受 $ne 的老接口。防守方则要明白:数据库的查询语法和接口设计之间的缝隙,就是漏洞的滋生地。

下次测 AI 应用时,别只盯着提示注入。看它后端用了什么数据库,然后往 JSON 里塞个操作符,说不定惊喜就来敲门了。


免责声明:

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

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

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

本文转载自:昆仑AI安全实验室 逍遥 逍遥《{“$ne”:”2026″}:我在某AI平台的登录框里贴了个操作符,变成了任意用户的“影子”》

评论:0   参与:  0