fix(security): 代码审查安全加固 — 三批次修复(6H/13M/12L)

第一批(快速修复):
- H6: main.py --debug 默认值 True→False,防止 Werkzeug RCE
- M2+M3: /search 增加 validate_query + top_k 范围限制(1-50)
- M4: context_count 范围限制(0-10) + 异常捕获
- L3: assert → raise RuntimeError(生产环境 API Key 检查)
- H1: SSE 错误事件移除 traceback 字段

第二批(安全加固):
- H2+H3: 文档接口路径遍历 realpath 校验 + 文件类型/大小限制
- H4+H5: 批量上传文件大小检查
- M6: LIKE 查询通配符转义
- M1: 37 处 str(e) 异常信息统一脱敏(6 文件)
- M5: CORS 生产环境限制来源
- M7: SESSION_MANAGER None 保护(503)
- M11: subprocess 参数注入防护(白名单 + -- 分隔符)

第三批(架构改进):
- M8+M9: 提取 JSON 解析共享工具(extract_json_object/list)
- M10: Prompt 注入检测防御(prompt_guard.py)
- M12: 解析器文件大小限制(Excel 50MB/TXT 20MB/PDF 100MB)
- M13: 全局单例竞态条件双重检查锁定(engine/bm25/intent_analyzer)
This commit is contained in:
lacerate551
2026-06-05 15:26:32 +08:00
parent a7206377cc
commit 90b915232a
19 changed files with 436 additions and 102 deletions

View File

@@ -14,6 +14,7 @@ BM25 关键词检索索引
import os
import pickle
import threading
import numpy as np
from rank_bm25 import BM25Okapi
import jieba
@@ -105,24 +106,27 @@ class BM25Index:
# ==================== 全局 BM25 索引管理器 ====================
_bm25_indexer: BM25Index = None
_bm25_lock = threading.Lock() # 单例创建锁,防止多线程竞态条件
def get_bm25_indexer() -> BM25Index:
"""
获取全局 BM25 索引器实例
获取全局 BM25 索引器实例(双重检查锁定,线程安全)
Returns:
BM25Index 实例
"""
global _bm25_indexer
if _bm25_indexer is None:
_bm25_indexer = BM25Index()
with _bm25_lock:
if _bm25_indexer is None:
_bm25_indexer = BM25Index()
return _bm25_indexer
def init_bm25_indexer(ids=None, documents=None, metadatas=None) -> BM25Index:
"""
初始化 BM25 索引器并添加文档
初始化 BM25 索引器并添加文档(加锁,线程安全)
Args:
ids: 文档 ID 列表
@@ -133,7 +137,8 @@ def init_bm25_indexer(ids=None, documents=None, metadatas=None) -> BM25Index:
初始化后的 BM25Index 实例
"""
global _bm25_indexer
_bm25_indexer = BM25Index()
if ids and documents:
_bm25_indexer.add_documents(ids, documents, metadatas or [])
with _bm25_lock:
_bm25_indexer = BM25Index()
if ids and documents:
_bm25_indexer.add_documents(ids, documents, metadatas or [])
return _bm25_indexer