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:
@@ -41,6 +41,7 @@ from auth.gateway import require_gateway_auth
|
||||
from auth.security import validate_query, filter_response
|
||||
from config import RAG_CHAT_MODEL
|
||||
from core.llm_utils import call_llm, call_llm_stream
|
||||
from core.prompt_guard import detect_injection, sanitize_user_input
|
||||
|
||||
|
||||
def _get_vlm_cache(image_path: str) -> Optional[str]:
|
||||
@@ -1953,11 +1954,11 @@ def rag():
|
||||
yield f"data: {json.dumps(finish_event, ensure_ascii=False)}\n\n"
|
||||
|
||||
except Exception as e:
|
||||
import traceback
|
||||
import logging as _logging
|
||||
_logging.getLogger(__name__).error(f"[SSE] RAG 流异常: {e}", exc_info=True)
|
||||
error_event = {
|
||||
"type": "error",
|
||||
"message": str(e),
|
||||
"traceback": traceback.format_exc()
|
||||
"message": "服务内部错误,请稍后重试"
|
||||
}
|
||||
yield f"data: {json.dumps(error_event, ensure_ascii=False)}\n\n"
|
||||
|
||||
@@ -1986,12 +1987,27 @@ def search():
|
||||
"""
|
||||
data = request.json or {}
|
||||
query = data.get('query', '')
|
||||
query = sanitize_user_input(query)
|
||||
injection_matches = detect_injection(query)
|
||||
if injection_matches:
|
||||
logger.warning(f"[Chat] 检测到可疑注入: {injection_matches}")
|
||||
top_k = data.get('top_k', 5)
|
||||
collections = data.get('collections') # 后端传入的知识库列表
|
||||
|
||||
if not query:
|
||||
return jsonify({'error': 'query is required'}), 400
|
||||
|
||||
# 输入安全校验(注入检测、违禁词、长度限制)
|
||||
is_valid, reason = validate_query(query)
|
||||
if not is_valid:
|
||||
return jsonify({'error': reason}), 400
|
||||
|
||||
# top_k 范围校验
|
||||
try:
|
||||
top_k = max(1, min(int(top_k), 50))
|
||||
except (ValueError, TypeError):
|
||||
top_k = 5
|
||||
|
||||
# 如果没有指定 collections,使用默认的公开库
|
||||
if not collections:
|
||||
collections = ['public_kb']
|
||||
|
||||
Reference in New Issue
Block a user