Skip to content

fix: P0+P1+P2 安全/并发/健壮性/运维修复 + 模型解耦以支持测试 - #16

Open
lugondev wants to merge 3 commits into
xinnan-tech:mainfrom
lugondev:fix/p0-security-concurrency
Open

fix: P0+P1+P2 安全/并发/健壮性/运维修复 + 模型解耦以支持测试#16
lugondev wants to merge 3 commits into
xinnan-tech:mainfrom
lugondev:fix/p0-security-concurrency

Conversation

@lugondev

@lugondev lugondev commented Jul 18, 2026

Copy link
Copy Markdown

概述 / Summary

本 PR 修复一组 P0/P1/P2 级安全、并发、健壮性与运维问题,并将模型加载解耦以支持单元测试。改动保持对外 API 行为不变,新增 27 个测试用例(无需真实 MySQL / 模型即可运行)。

This PR fixes P0/P1/P2 security, concurrency, robustness & ops issues and decouples model loading to make the service testable. Public API behavior is unchanged; adds 27 tests that run without a real MySQL or the model.


P0

🔒 安全 / Security

  • 令牌校验改为常量时间比较security.pyhealth.py 使用 secrets.compare_digest,避免定时攻击。
  • 不再将令牌/密钥写入日志:原先失败时会记录 authorization[:20] 或完整 key,存在密钥泄露风险,现已移除。

⚡ 并发 / Concurrency

  • 数据库连接池connection.py 改用 DBUtils.PooledDB,惰性创建、每次请求借用独立连接,解决全局单连接在并发下被共享的问题。
  • 推理放入线程池:接口层用 run_in_threadpool 调用阻塞型服务方法,避免阻塞 async 事件循环。

🧪 可测试性 / Testability

  • 模型惰性加载VoiceprintService 构造时不再加载模型;pipeline 属性首次访问时加载。导入模块不再触发模型下载。
  • 预热显式化warmup()lifespan 启动时调用;VOICEPRINT_SKIP_WARMUP=1 可跳过(测试用)。
  • 依赖注入:新增 get_voiceprint_service 便于测试替身注入。

P1

🌐 CORS (1.5)

  • 来源与凭证改由配置决定(server.cors_origins / server.cors_allow_credentials)。
  • build_cors_config:检测到通配来源 "*"allow_credentials=True 的不安全组合时自动关闭凭证。

🎧 音频校验 / Audio validation (1.6)

  • 注册/识别在推理前统一校验音频(最小/最大字节数 + 时长/采样率),不合法直接拒绝,避免无谓推理与超大文件的内存/DoS 风险。
  • 新增配置 voiceprint.max_audio_bytes(默认 10MB)。

🎚️ 相似度阈值 / Threshold (1.4)

  • 默认阈值 0.2 → 0.5(更保守,降低误接受风险)。生产环境仍应结合真实数据标定(如按 EER 调整)。

P2

🧹 残留临时文件 / Stale temp files

  • 新增 AudioProcessor.cleanup_stale_temp_files,清理进程被强杀时遗留的过期临时文件;应用启动时调用。

♻️ 生命周期 / Lifecycle

  • 关闭时释放数据库连接池 db_connection.close(),替代原 __del__ 清理;启动/关闭统一在 lifespan 管理。

📦 Docker 模型缓存 / Model cache

  • MODELSCOPE_CACHE 指向持久化的 data 卷(/app/data/modelscope_cache),模型只需下载一次,容器重建后复用,避免每次重新下载。

验证 / Verification

$ python -m pytest
27 passed

依赖 / Dependencies

  • 新增 DBUtils==3.1.2

🤖 Generated with Claude Code

lugondev and others added 2 commits July 18, 2026 22:55
安全:
- 令牌校验改用 secrets.compare_digest 常量时间比较,避免定时攻击
  (app/core/security.py, app/api/v1/health.py)
- 不再将令牌/密钥内容写入日志,防止密钥泄露

并发/性能:
- 数据库改用 DBUtils 连接池,惰性创建,每次请求借用独立连接,
  避免全局单连接在并发下被共享 (app/database/connection.py)
- 接口层将阻塞型推理调用放入线程池 (run_in_threadpool),
  避免阻塞事件循环 (app/api/v1/voiceprint.py)

可测试性:
- 模型改为惰性加载 (pipeline 属性 + 双重检查锁),导入模块不再加载模型;
  预热改为显式 warmup(),由应用 lifespan 启动时调用
  (VOICEPRINT_SKIP_WARMUP=1 可跳过,便于测试)
- 引入依赖注入 get_voiceprint_service,便于测试替身注入
- 新增 pytest 测试套件 (15 用例,覆盖连接层/服务层/令牌校验/接口)

清理:
- pydantic v1 Config 迁移到 v2 model_config,Query example -> examples
- 新增依赖 DBUtils==3.1.2

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
CORS (1.5):
- 来源与凭证改由配置决定 (server.cors_origins / cors_allow_credentials)
- 新增 build_cors_config 强制修正不安全组合:通配来源 "*" 与
  allow_credentials=True 不兼容时自动关闭凭证 (app/application.py)

音频校验 (1.6):
- 注册/识别在推理前统一校验音频:最小/最大字节数 + 时长/采样率
  (VoiceprintService._audio_bytes_valid),不合法直接拒绝,避免无谓推理与
  超大文件的内存/DoS 风险
- 新增配置 voiceprint.max_audio_bytes(默认10MB)

相似度阈值 (1.4):
- 默认阈值 0.2 -> 0.5(更保守,降低误接受风险);生产需结合真实数据标定
- voiceprint.yaml 补充 voiceprint 段与 CORS 说明

测试:
- 新增 test_cors / test_audio_validation / test_config,共 9 用例
- 全套 24 用例通过(无需真实 MySQL / 模型)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@lugondev lugondev changed the title fix: P0 安全与并发修复 + 模型解耦以支持测试 (compare_digest / 连接池 / 线程池 / 惰性加载) fix: P0+P1 安全/并发/健壮性修复 + 模型解耦以支持测试 Jul 18, 2026
临时文件:
- 新增 AudioProcessor.cleanup_stale_temp_files,清理进程被强杀时遗留的
  过期临时文件;在应用启动时调用

生命周期:
- 关闭时释放数据库连接池 (db_connection.close()),替代原 __del__ 清理
- 启动时清理残留临时文件 + 预热模型,统一在 lifespan 管理

Docker 模型缓存:
- MODELSCOPE_CACHE 指向持久化的 data 卷 (/app/data/modelscope_cache),
  模型只需下载一次,容器重建后复用,避免每次重新下载

测试:
- 新增 test_audio_cleanup / test_lifecycle,全套 27 用例通过

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@lugondev lugondev changed the title fix: P0+P1 安全/并发/健壮性修复 + 模型解耦以支持测试 fix: P0+P1+P2 安全/并发/健壮性/运维修复 + 模型解耦以支持测试 Jul 18, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant