---

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 }

落地建议

  • 在入口统一执行键过滤与算子白名单,拒绝非法键与算子。
  • 执行分页与类型限制,避免超大数组与过长字符串造成资源耗尽。
  • 审计拒绝查询与异常输入,便于优化与防御策略迭代。

验证清单

  • 查询是否仅包含白名单算子与合法键。
  • 分页与类型是否在限制范围内。

点赞(0) 打赏

评论列表 共有 0 条评论

暂无评论
立即
投稿

微信公众账号

微信扫一扫加关注

发表
评论
返回
顶部