mongodb防注入关键在于显式校验用户输入字段类型、格式及操作符,而非依赖pymongo或mongoose自动防护;直接将req.body塞入find()等查询会导致{"$ne": null}等恶意bson绕过验证。

Python 3.11 本身不直接导致 MongoDB 注入,但你在用 PyMongo 或 Mongoose(通过 Flask/FastAPI 等框架)构造查询时,若把用户输入原样塞进 find()、findOne() 或 aggregate() 的查询对象里,就等于给攻击者开了后门——这不是版本问题,是写法问题。
为什么 PyMongo + req.body 直接进 find() 就危险
MongoDB 查询接受任意合法 BSON 结构,而 PyMongo 会原样序列化 Python 字典。攻击者提交 {"$ne": ""} 这样的字典,后端不做校验就传给 collection.find({"username": req_body["username"]}),结果就是“只要 username 不等于空字符串就匹配”,登录绕过、权限提升全都有可能。
常见错误现象:
• 登录接口输 {"$ne": null} 当用户名,任意密码都能进
• 搜索接口填 {"$regex": ".*"},查出全库用户
- PyMongo 4.x+ 默认不开启严格模式,
find({})里嵌套对象不会自动拒绝 -
json.loads()再解析一次请求体?别干这事——可能触发原型污染或 DoS,纯属画蛇添足 - Flask 的
request.get_json()或 FastAPI 的Body参数默认就解析成 dict,你拿到的已经是“可执行结构”了
对每个查询字段做显式类型+格式校验
别指望框架自动拦住 $ne 或 $where,必须在业务逻辑层卡死。比如 username 字段只该是 3–20 位字母数字下划线:
if not isinstance(req_body.get("username"), str) or not re.match(r"^[a-zA-Z0-9_]{3,20}$", req_body["username"]):
return JSONResponse({"error": "Invalid username"}, status_code=400)
-
isinstance(..., str)比type(...) == str更安全,能防子类绕过 - 正则必须锚定首尾(
^...$),否则"admin\0{$ne:1}"可能漏检 -
None、list、dict、int必须被拒——这些都不是合法用户名
禁用高危操作符:$where、$regex、$expr 的输入必须受控
$where 能执行任意 JavaScript,$regex 若不转义可被用于全库遍历,$expr 支持表达式计算——三者合起来就是 NoSQL 注入的黄金通道。
错误写法:db.users.find({"name": {"$regex": user_input}})
正确做法:
• 先用 re.escape() 转义用户输入
• 强制加 $options: "i" 且禁止用户控制选项
• 绝不把原始输入丢进 $where 或 $expr
escaped = re.escape(user_input)
db.users.find({"name": {"$regex": f"^{escaped}$", "$options": "i"}})
-
$regex以^开头才可能走索引,盲目放开等于放弃性能和安全 -
$where在 PyMongo 中基本没理由用——所有逻辑都该移到应用层 - 如果真要用
$expr,确保内部字段名和操作符都是白名单内的常量,而非拼接而来
MongoDB 连接与权限配置不能省
即使代码层防住了,数据库账号权限过大也会放大风险。PyMongo 连接字符串里别用 root,也别开 bindIp: 0.0.0.0 暴露到公网。
- 创建最小权限账号:
db.createUser({user:"app_user", pwd:"...", roles:[{role:"readWrite", db:"myapp"}]}) - 连接时显式指定数据库名,避免意外写到
admin或其他库:MongoClient("mongodb://app_user:pwd@localhost:27017/myapp") - 禁用
serverSelectionTimeoutMS=5000以外的长连接超时,防止慢速 DoS
最易被忽略的一点:Mongoose 用户注意,6.0+ 默认启用 strictQuery: true,但老项目升级后若没配这个,{username: {"$ne": ""}} 仍会被静默忽略字段——你以为挡住了,其实只是查询没生效,掩盖了真实漏洞。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











