---
title: NoSQL注入防护(MongoDB/查询算子白名单)最佳实践
keywords:
- NoSQL注入
- MongoDB
- 查询算子
- 白名单
- 键过滤
description: 通过MongoDB查询算子白名单与键过滤、类型校验与分页限制,系统性防止NoSQL注入与资源耗尽。
tags:
- MongoDB
- NoSQL注入
- 工程实践
- 数据安全
- 查询算子
- 白名单
- 输入校验
- 键过滤
categories:
- 文章资讯
- 技术教程
---
背景与价值
NoSQL注入常通过构造非法算子与键。统一白名单与键过滤可防止绕过与非法查询。
统一规范
- 算子白名单:仅允许受控算子如
$eq/$in/$gte/$lte。 - 键过滤:拒绝包含
.或以$开头的键。 - 分页限制:统一页大小与最大偏移,防止资源耗尽。
核心实现
算子与键过滤
type Query = Record<string, any>
const allowOps = new Set(['$eq','$in','$gte','$lte','$ne'])
function validKey(k: string): boolean { return !k.startsWith('$') && !k.includes('.') && /^[a-zA-Z_][a-zA-Z0-9_]*$/.test(k) }
function filterQuery(q: Query): Query {
const out: Query = {}
for (const [k, v] of Object.entries(q)) {
if (!validKey(k)) continue
if (v && typeof v === 'object' && !Array.isArray(v)) {
const sub: Record<string, any> = {}
for (const [op, val] of Object.entries(v)) if (allowOps.has(op)) sub[op] = val
out[k] = sub
} else {
out[k] = v
}
}
return out
}
分页限制与类型校验
type Page = { page: number; size: number }
function normalizePage(p: Page): Page { const size = Math.min(100, Math.max(1, Math.floor(p.size || 20))); const page = Math.max(1, Math.floor(p.page || 1)); return { page, size } }
function validValue(v: any): boolean { if (typeof v === 'string') return v.length <= 1024; if (typeof v === 'number') return Number.isFinite(v); if (Array.isArray(v)) return v.length <= 100; return true }
function sanitize(q: Query): Query { const out: Query = {}; for (const [k, v] of Object.entries(filterQuery(q))) { if (validValue(v)) out[k] = v }; return out }
落地建议
- 在入口统一执行键过滤与算子白名单,拒绝非法键与算子。
- 执行分页与类型限制,避免超大数组与过长字符串造成资源耗尽。
- 审计拒绝查询与异常输入,便于优化与防御策略迭代。
验证清单
- 查询是否仅包含白名单算子与合法键。
- 分页与类型是否在限制范围内。

发表评论 取消回复