You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用PyMongo时如何正确sanitize含$in的查询以规避注入风险

解决mongosanitizer过滤合法MongoDB操作符的问题

问题根源

mongosanitizer的默认sanitize行为会过滤所有以$开头的键——这类键多为MongoDB操作符,工具默认认为用户输入中不应包含此类内容以防范NoSQL注入。但像$in这类合法查询操作符被误过滤后,就会导致数组查询失效。

解决方案

1. 显式指定允许保留的合法操作符

调用sanitize时,通过allowed_keys参数传入需要保留的操作符列表,让工具仅过滤非法键,保留合法的MongoDB操作符。

示例代码:

from mongosanitizer.sanitizer import sanitize
from bson.objectid import ObjectId

# 定义业务中需要用到的合法MongoDB操作符
ALLOWED_OPERATORS = {'$in', '$eq', '$ne', '$gt', '$lt'}

# 处理用户输入的ID列表,先验证并转换为ObjectId
valid_req_ids = []
for id_str in user_provided_ids:
    if ObjectId.is_valid(id_str):
        valid_req_ids.append(ObjectId(id_str))
    # 非法ID可选择跳过或抛出错误处理

# 构造查询语句
find_query = {"_id": {"$in": valid_req_ids}}

# 执行 sanitize,保留允许的操作符
sanitize(find_query, allowed_keys=ALLOWED_OPERATORS)

# 执行数据库操作
e = client[db_name]['request'].find_one_and_update(
    filter=find_query,
    update={'$unset': reset_data},
    return_document=ReturnDocument.AFTER
)

2. 提前严格验证用户输入

无论是否使用sanitize,都要确保用户提供的ID是合法的ObjectId:

  • 用ObjectId.is_valid()验证格式合法性
  • 非法ID直接过滤或抛出异常,避免恶意输入进入查询逻辑

3. 避免过度依赖sanitize

PyMongo本身支持参数化查询,只要不直接拼接查询字符串,而是使用PyMongo的查询对象(比如用ObjectId转换用户ID),就能有效防范NoSQL注入。原单条ID查询中ObjectId(request_id)的写法本身就是安全的,非法ID会直接抛出异常。

注意事项

  • allowed_keys只添加业务实际需要的操作符,不要盲目添加大量操作符,避免引入安全风险
  • 自定义的更新操作符(比如代码中的$unset)属于固定逻辑,不是用户输入内容,无需用sanitize处理

内容的提问来源于stack exchange,提问作者rcs

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.10 01:35:10