跳转至

灵知系统(ZhiNeng Knowledge System)全面代码审计报告

⚠️ **归档文档 — 数据已过时** 本报告为历史快照存档。当前版本 **v1.3.0-dev**,232 测试通过。 👉 最新工程状态请参阅 **[ENGINEERING_ALIGNMENT.md](ENGINEERING_ALIGNMENT.md)**

审计日期: 2026-03-30 审计范围: 全代码库 — 逐文件阅读分析所有 51 个核心源码文件 审计方法: 按依赖层次分 6 批并行读取,每个文件全量分析 已完成的修复阶段: Phase 1-6(路径遍历防护、API密钥保护、DB池统一部分、错误脱敏、LingFlow路径修复、jieba中文分词集成、Redis缓存修复、磁盘清理) 测试基线: 251 passed, 13 failed(均为预存的DB连接问题),零回归


目录

  1. 系统架构概览
  2. 🔴 CRITICAL — 必须立即修复
  3. 🟠 HIGH — 高优先级修复
  4. 🟡 MEDIUM — 中等优先级
  5. 🟢 LOW — 代码质量与清理
  6. LingFlow 启用分析
  7. 审计发现汇总表
  8. 修复优先级路线图(Phase 7-12)

1. 系统架构概览

Frontend (Vue) → Nginx:8008 → API:8000 (FastAPI)
                                    ├── Middleware: CORS, Security Headers, Rate Limit, GZip, Request Logging
                                    ├── Lifespan: ServiceManager → {DatabaseService, CacheService, VectorService, MonitoringService}
                                    ├── Auth(已构建但未激活): JWT RS256 + RBAC + AuthMiddleware
                                    ├── API v1 路由:
                                    │   ├── /api/v1/documents — CRUD
                                    │   ├── /api/v1/search — 关键词 + 混合 + 提问 + 分类 + 统计
                                    │   ├── /api/v1/health — 健康检查 + 缓存管理
                                    │   ├── /api/v1/gateway — 领域路由 + 指标 + Prometheus
                                    │   ├── /api/v1/reasoning — CoT + ReAct + GraphRAG
                                    │   └── /api/v1/textbook-processing — LingFlow 教材处理
                                    ├── 领域: 气功, 中医, 儒家, 通用
                                    ├── 网关: Router + Rate Limiter + Circuit Breaker
                                    ├── 缓存: L1 (内存) + L2 (Redis)
                                    └── 监控: 健康检查 + 指标 + Prometheus Exporter

代码量统计

模块 文件数 大致行数 状态
backend/auth/ 4 ~2,685 ⚠️ 已构建,未启用
backend/api/v1/ 7 ~1,391 ✅ 运行中
backend/core/ 7 ~1,350 ✅ 运行中
backend/services/ 6 ~1,545 ⚠️ 向量搜索为桩代码
backend/textbook_processing/ 3 ~2,288 ✅ 路径已修复
backend/cache/ 3 ~1,560 ✅ 运行中
backend/gateway/ 3 ~804 ✅ 运行中
backend/domains/ 3 ~500 ✅ 运行中
backend/config/ 6 ~756 ⚠️ 配置冲突
backend/monitoring/ 4 ~445 ⚠️ aioredis过时
backend/common/ 2 ~314 ⚠️ SQL注入风险
总计 ~51 ~14,000+

已读取的全部文件清单

展开查看完整文件列表(51个文件,全部逐行审计) **Batch 1 — Config 系统 (756行)** - `backend/config/__init__.py` (163行) - `backend/config/base.py` (114行) - `backend/config/database.py` (135行) - `backend/config/redis.py` (103行) - `backend/config/security.py` (126行) - `backend/config/lingzhi.py` (115行) **Batch 2 — API路由层 (1,391行)** - `backend/api/v1/__init__.py` (21行) - `backend/api/v1/documents.py` (93行) - `backend/api/v1/search.py` (226行) - `backend/api/v1/health.py` (212行) - `backend/api/v1/gateway.py` (255行) - `backend/api/v1/reasoning.py` (289行) - `backend/api/v1/textbook_processing.py` (295行) **Batch 3 — 业务逻辑 (3,584行)** - `backend/services/retrieval/vector.py` (263行) - `backend/services/retrieval/hybrid.py` (201行) - `backend/services/retrieval/bm25.py` (236行) - `backend/services/textbook_service.py` (306行) - `backend/services/compression.py` (528行) - `backend/textbook_processing/autonomous_processor.py` (962行) - `backend/textbook_processing/workflow.py` (808行) - `backend/textbook_processing/deep_toc_parser.py` (518行) **Batch 4 — 基础设施层 (~2,980行)** - `backend/cache/manager.py` (858行) - `backend/cache/redis_cache.py` (615行) - `backend/gateway/router.py` (285行) - `backend/gateway/rate_limiter.py` (265行) - `backend/gateway/circuit_breaker.py` (254行) - `backend/domains/base.py` (216行) - `backend/domains/registry.py` (281行) - `backend/common/db_helpers.py` (206行) **Batch 5 — Auth系统 (~2,685行)** - `backend/auth/__init__.py` (129行) - `backend/auth/jwt.py` (810行) - `backend/auth/middleware.py` (628行) - `backend/auth/rbac.py` (1,118行) **Batch 6 — 部署与附加 (3,015+行)** - `docker-compose.yml` (226行) - `nginx/nginx.conf` (72行) - `backend/Dockerfile` (32行) - `backend/main.py` (83行) - `backend/core/lifespan.py` (228行) - `backend/core/middleware.py` (134行) - `backend/core/services.py` (337行) - `backend/core/service_manager.py` (334行) - `backend/core/database.py` (50行) - `backend/core/dependency_injection.py` (316行) - `backend/core/request_stats.py` (21行) - `backend/monitoring/__init__.py` (30行) - `backend/monitoring/health.py` (298行) - `backend/monitoring/metrics.py` (293行) - `backend/monitoring/prometheus.py` (133行) - `backend/cache/__init__.py` (77行) - `backend/cache/decorators.py` (698行) - `backend/gateway/__init__.py` (17行) - `backend/domains/__init__.py` (25行) - `backend/common/__init__.py` (32行) - `backend/utils/path_validation.py` (108行)

2. CRITICAL — 必须立即修复

🔴 C-1: 向量搜索为桩代码(STUB)— 所有语义搜索返回垃圾结果

文件: backend/services/retrieval/vector.py:79-95 严重性: 🔴 CRITICAL 影响: 所有向量搜索、混合搜索、GraphRAG推理的结果均不可信

# vector.py:79-95 — embed_text() 的实际实现
# TODO: 集成实际的BGE嵌入服务
# 目前使用简单哈希模拟(生产环境需替换)
import hashlib

hash_obj = hashlib.sha256(text.encode('utf-8'))
hash_bytes = hash_obj.digest()

# 扩展到1024维
vector = []
for i in range(self.embedding_dim):
    byte_idx = i % len(hash_bytes)
    val = (hash_bytes[byte_idx] / 255.0 - 0.5) * 2
    vector.append(val)

# 归一化
norm = sum(v * v for v in vector) ** 0.5
vector = [v / norm for v in vector]

问题: - hashlib.sha256 生成的是确定性伪随机数,不是语义向量 - 相似的文本不会得到相似的向量,不同的文本也不会被区分 - 整个1024维向量仅由32字节(256位)的哈希循环填充,信息量极低 - search_by_vector() 同样是桩代码 - 注释明确说 "TODO: 集成实际的BGE嵌入服务" 和 "生产环境需替换"

影响范围: - POST /api/v1/search/hybrid — 混合搜索(BM25 + 向量) - POST /api/v1/reasoning/graphrag — GraphRAG推理 - backend/services/retrieval/hybrid.py — RRF融合排序 - 所有依赖向量相似度的功能

修复方案: 集成真实嵌入模型(BGE-M3 / text2vec-large-chinese / OpenAI embeddings)


🔴 C-2: 认证系统已构建但完全未启用

文件: backend/main.py:49-67(中间件注册), backend/auth/(~2,685行代码) 严重性: 🔴 CRITICAL 影响: 所有API端点完全开放,无认证

详细分析:

模块 文件 行数 状态
JWT auth/jwt.py 810 ✅ 完整实现(RS256、黑名单、刷新令牌)
中间件 auth/middleware.py 628 ✅ 完整实现
RBAC auth/rbac.py 1,118 ✅ 完整实现(权限、角色、条件)
导出 auth/__init__.py 129 ✅ 完整实现

未启用的证据 (main.py:49-67):

# main.py 中注册的5个中间件:
app.add_middleware(CORSMiddleware, ...)        # CORS
app.middleware("http")(add_security_headers)   # 安全头
app.middleware("http")(log_requests)           # 请求日志
app.add_middleware(GZipMiddleware, ...)         # GZip
app.add_middleware(RateLimitMiddleware)         # 限流
# ❌ 没有 AuthMiddleware

完全开放的端点: - POST /api/v1/documents — 创建文档(无认证) - POST /api/v1/search/embeddings/update — 更新嵌入(无认证) - POST /api/v1/gateway/query — 网关查询(无认证) - POST /api/v1/domains/{name}/query — 领域查询(无认证) - POST /api/v1/reasoning/* — 所有推理端点(无认证)

修复方案: 在 main.py 中添加 AuthMiddleware,为路由添加认证依赖


🔴 C-3: SQL注入 — db_helpers.py 中 f-string 拼接 SQL

文件: backend/common/db_helpers.py:98-103 严重性: 🔴 CRITICAL(升级自HIGH — 直接SQL注入向量) 影响: 如果 query 参数来源可被用户控制,攻击者可执行任意SQL

# db_helpers.py:98-103 — fetch_paginated() 函数
count_query = f"SELECT COUNT(*) FROM ({query}) AS subq"        # ← 直接拼接
total = await pool.fetchval(count_query, *args)

# 获取分页数据
paginated_query = f"{query} ORDER BY id LIMIT ${len(args) + 1} OFFSET ${len(args) + 2}"
rows = await pool.fetch(paginated_query, *args, limit, offset)  # ← 直接拼接

问题: query 参数通过 f-string 直接插入到 SQL 语句中。虽然当前调用者的 query 都是硬编码字符串,但函数签名接受任意字符串,一旦有调用者传入用户控制的查询,即为 SQL 注入。

修复方案: 1. 将 query 参数改为枚举或白名单验证 2. 或者将整个函数标记为内部API,禁止传入动态SQL


🔴 C-4: LingFlow workflow.py 中遗留的 sys.path hack(step4/step5未修复)

文件: backend/textbook_processing/workflow.py:508-509, 576-577 严重性: 🔴 CRITICAL(针对LingFlow启用) 影响: step4 和 step5 的导入会因路径错误而失败

# workflow.py:508-509 — step4_import_to_db() 中
import sys
sys.path.insert(0, str(self.project_root / "backend" / "lingflow"))  # ← 路径已不存在

# workflow.py:576-577 — step5 中
import sys
sys.path.insert(0, str(self.project_root / "scripts"))  # ← 路径可能不存在

背景: Phase 5 修复了 step3 的路径问题(line 423),但遗漏了 step4 (line 508) 和 step5 (line 577)。

修复方案: 更新为 backend/textbook_processing/ 路径


3. HIGH — 高优先级修复

🟠 H-1: Config 单例线程不安全 — get_config() 无锁保护

文件: backend/config/__init__.py:88-101 严重性: 🟠 HIGH 影响: 并发初始化时可能创建多个 Config 实例

# config/__init__.py:88-101
_config: Optional[Config] = None
_config_lock = asyncio.Lock()    # ← 锁存在但...


def get_config() -> Config:       # ← 同步函数,不使用 _config_lock
    """获取配置实例(单例模式)"""
    global _config
    if _config is None:
        _config = Config()        # ← 竞态条件
    return _config

_config_lock 在 line 89 定义但 get_config() 是同步函数,无法使用 asyncio.Lock。只有 reload_config() 使用了该锁。

修复方案: 使用 threading.Lock 替代 asyncio.Lock,在 get_config() 中加锁。


🟠 H-2: ServiceManager 单例无锁保护

文件: backend/core/service_manager.py:315-328 严重性: 🟠 HIGH

# service_manager.py:315-328
_global_service_manager: Optional[ServiceManager] = None

def get_service_manager() -> ServiceManager:
    global _global_service_manager
    if _global_service_manager is None:
        _global_service_manager = ServiceManager()  # ← 无锁,竞态条件
    return _global_service_manager

与 H-1 相同模式。ServiceManager 自身有 self._lock = asyncio.Lock() (line 110),但工厂函数无保护。

修复方案: 使用 threading.Lock 保护单例创建。


🟠 H-3: Redis URL 双源冲突 — REDIS_URL vs get_redis_url()

文件: backend/config/redis.py:21-24 + backend/config/redis.py:87-91 严重性: 🟠 HIGH 影响: Docker 环境下实际使用的 Redis URL 可能与配置不一致

# redis.py:21-24 — 字段默认值
REDIS_URL: str = Field(
    default="redis://localhost:6379/0",
    description="Redis连接URL"
)

# redis.py:87-91 — 方法构建URL
def get_redis_url(self) -> str:
    if self.REDIS_PASSWORD:
        return f"redis://:{self.REDIS_PASSWORD}@{self.REDIS_HOST}:{self.REDIS_PORT}/{self.REDIS_DB}"
    return f"redis://{self.REDIS_HOST}:{self.REDIS_PORT}/{self.REDIS_DB}"

冲突: - Docker Compose 设置 REDIS_URL=redis://redis:6379/0(容器名解析) - REDIS_HOST 默认 localhost(不在 Docker 中) - get_redis_url() 从组件构建,忽略 REDIS_URL 字段 - Phase 6 修复了 services.py:133 使用 config.get_redis_url(),但这依赖组件配置正确

修复方案: get_redis_url() 应优先返回 REDIS_URL(如果已设置),仅在没有完整URL时从组件构建。


🟠 H-4: 健康检查泄露数据库错误详情

文件: backend/core/lifespan.py:154-159 + backend/common/db_helpers.py:201-205 严重性: 🟠 HIGH 影响: 内部错误详情(可能含连接串)暴露给API调用者

# lifespan.py:154-159
except Exception as e:
    return HealthCheckResult(
        name="database",
        status=HealthStatus.UNHEALTHY,
        message=f"数据库连接失败: {str(e)}"  # ← 泄露完整错误
    )

# db_helpers.py:201-205
return {
    "status": "degraded",
    "database": f"error: {str(e)}",  # ← 泄露完整错误
    "timestamp": datetime.now().isoformat(),
}

asyncpg 的异常消息通常包含完整的连接字符串(主机、端口、数据库名、用户名)。

修复方案: 使用通用错误消息,将详细信息仅记录到日志。


🟠 H-5: 数据库连接池大小硬编码,忽略配置

文件: backend/core/database.py:28-34 严重性: 🟠 HIGH

# database.py:28-34
db_pool = await asyncpg.create_pool(
    database_url,
    min_size=10,           # ← 硬编码
    max_size=50,           # ← 硬编码
    command_timeout=30,
    max_inactive_connection_lifetime=300
)

Config 类有 DB_POOL_SIZE 字段,但 init_db_pool() 从不读取它。直接使用 os.getenv("DATABASE_URL") (line 22) 而非配置系统。

修复方案: 从 get_config() 读取池大小配置。


🟠 H-6: Triple 数据库连接池问题

文件: 多个文件 严重性: 🟠 HIGH 影响: 连接泄漏、资源浪费

池来源 文件 创建方式
池 #1 core/lifespan.py 通过 DatabaseService.start()
池 #2 core/services.py VectorService.start() 再次调用 init_db_pool()
池 #3 core/dependency_injection.py 弃用的 _db_pool 仍存在

修复方案: 统一为单一池,通过 app.state.db_pool 共享。


🟠 H-7: 写入端点无认证

严重性: 🟠 HIGH(依赖 C-2 修复)

以下端点接受写入操作但完全无认证:

端点 方法 风险
/api/v1/documents POST 创建任意文档
/api/v1/search/embeddings/update POST 修改嵌入数据
/api/v1/reasoning/* POST 推理调用(消耗API配额)

4. MEDIUM — 中等优先级

🟡 M-1: Redis 健康检查使用过时的 aioredis API

文件: backend/monitoring/health.py:262-263 严重性: 🟡 MEDIUM

# health.py:262-263
import aioredis                                               # ← 过时
redis = await aioredis.from_url(redis_url)                    # ← 过时API

aioredis 已合并到 redis>=4.2.0。应使用 import redis.asyncio as aioredis


🟡 M-2: 模块级可变全局状态(非线程安全)

文件: backend/api/v1/search.py:23-33, backend/api/v1/reasoning.py:22-24

# search.py:23
_hybrid_retriever: Optional[HybridRetriever] = None  # ← 模块级可变全局

# reasoning.py:22-24
_cot_reasoner: Optional[ChainOfThoughtReasoner] = None
_react_reasoner: Optional[ReActReasoner] = None
_graphrag_reasoner: Optional[GraphRAGReasoner] = None

多个协程可能同时读写这些全局变量。


🟡 M-3: 网关限流硬编码 client_ip — 所有用户共享限流桶

文件: backend/api/v1/gateway.py:85 严重性: 🟡 MEDIUM

# gateway.py:85
client_ip = "default"  # 实际应用中应从请求中获取

所有用户共享同一个 "default" 限流桶,一个用户的请求会影响所有用户。

修复方案: 从 Request.client 或 X-Forwarded-For 头提取真实IP。


🟡 M-4: 任务ID生成基于秒级时间戳 — 并发冲突

文件: backend/api/v1/textbook_processing.py:152, 218 严重性: 🟡 MEDIUM

# textbook_processing.py:152
task_id = f"task_{datetime.now().strftime('%Y%m%d_%H%M%S')}"

# textbook_processing.py:218
task_id = f"batch_{datetime.now().strftime('%Y%m%d_%H%M%S')}"

同一秒内的并发请求会产生相同的 task_id,后者覆盖前者。

修复方案: 使用 uuid.uuid4() 或加入毫秒/随机后缀。


🟡 M-5: RBACManager.init 中调用 asyncio.create_task

文件: backend/auth/rbac.py:522 严重性: 🟡 MEDIUM

# rbac.py:522 — 在 __init__ 中
asyncio.create_task(self._initialize_default_users())

如果实例化时没有运行中的事件循环(如模块导入、测试环境),会抛出 RuntimeError

修复方案: 改为显式的异步初始化方法(async def initialize())。


🟡 M-6: 缓存端点泄露异常信息

文件: backend/api/v1/health.py:119, 137, 161, 192, 211 严重性: 🟡 MEDIUM

# health.py:119 — cache stats
return {"error": str(e), "enabled": False}

# health.py:137 — cache metrics
return {"error": str(e), "enabled": False}

# health.py:161 — prometheus endpoint
content=f"# Error: {str(e)}"

# health.py:192, 211 — reset/clear endpoints
return {"status": "error", "message": str(e)}

5处异常直接暴露给API调用者,可能泄露内部路径、配置或堆栈信息。

修复方案: 使用通用错误消息 + 日志记录。


🟡 M-7: Nginx 缺少 client_max_body_size 配置

文件: nginx/nginx.conf(全文72行,无此指令) 严重性: 🟡 MEDIUM 影响: 教材文件上传(通常数MB至数十MB)会被 nginx 默认的 1MB 限制拒绝(413错误)

修复方案: 在 server 块中添加 client_max_body_size 100M;


🟡 M-8: Dockerfile CMD 使用开发模式 --reload

文件: backend/Dockerfile:32 严重性: 🟡 MEDIUM

CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000", "--reload"]

虽然 docker-compose.yml 覆盖了此命令,但直接 docker build && docker run 时会使用开发模式。

修复方案: 移除 --reload


🟡 M-9: LingZhiConfigDatabaseConfig 字段重复

文件: backend/config/lingzhi.py vs backend/config/database.py 严重性: 🟡 MEDIUM

字段 LingZhiConfig 行号 DatabaseConfig 行号
GUOXUE_DB_PATH line 22 line 28
KXZD_DB_PATH line 26 line 32
QUERY_TIMEOUT line 49 line 69
MAX_CONNECTIONS vs DB_MAX_CONNECTIONS line 56 line 61

MRO 导致 LingZhiConfig 值可能覆盖 DatabaseConfig 值。


🟡 M-10: LIKE 通配符注入

文件: backend/common/db_helpers.py:135 严重性: 🟡 MEDIUM

# db_helpers.py:135
search_pattern = f"%{search_term}%"

search_term 中的 %_ 不会被转义,用户可以通过输入 % 匹配所有行。虽然不是SQL注入(参数化安全),但影响查询准确性。

修复方案: search_term.replace('%', '\\%').replace('_', '\\_') 预处理。


🟡 M-11: Docker Compose postgres-exporter 端口错误

文件: docker-compose.yml:198 严重性: 🟡 MEDIUM

# docker-compose.yml:198
DATA_SOURCE_NAME: "postgresql://zhineng:${POSTGRES_PASSWORD:-zhineng123}@postgres:5436/zhineng_kb?sslmode=disable"

postgres:5436 错误。Docker 内部网络中 PostgreSQL 监听 5432(5436:5432 是宿主映射)。exporter 运行在同一 Docker 网络中,应使用内部端口 5432。


🟡 M-12: Config 模块级加载

文件: backend/config/__init__.py:137(近似) 严重性: 🟡 MEDIUM

config = get_config()  # 模块级执行

任何 from config import ... 都会立即创建 Config 实例,影响测试隔离。


🟡 M-13: 两套独立的限流系统

文件: backend/api/v1/gateway.py + backend/core/middleware.py 严重性: 🟡 MEDIUM

  1. 中间件层: RateLimitMiddleware — 全局请求限流
  2. 网关层: InMemoryRateLimiter — 端点级别限流

两者独立运行,互不感知,可能导致限流不一致。


🟡 M-14: Docker Compose 默认密码弱

文件: docker-compose.yml

POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-zhineng123}
REDIS_PASSWORD: ${REDIS_PASSWORD:-redis123}

ADMIN_API_KEYS 默认为 admin123


5. LOW — 代码质量与清理

🟢 L-1: 大量备份文件污染仓库

main.py.backup
main.py.backup_before_refactor
db_helpers.py.backup
docker-compose.yml.backup.*
docker-compose.yml.bad

修复: 删除所有 .backup 文件,依赖 Git 历史


🟢 L-2: 监控模块零测试覆盖

backend/monitoring/ 模块完全没有测试。健康检查、指标收集、Prometheus 导出器未经测试。


🟢 L-3: 未使用的核心模块

模块 行数 说明
common/singleton.py ~30 导出但从未被实际服务代码导入
core/config_watcher.py 197 零覆盖,集成路径不明
core/urgency_guard.py 184 零覆盖,集成路径不明
core/data_verification_gate.py ~190 零覆盖,集成路径不明

🟢 L-4: Elasticsearch 已部署但未使用

docker-compose.yml 包含 tcm-elasticsearch 服务(运行中),但代码中没有 Elasticsearch 集成。BM25 使用内存索引,浪费了已部署的 ES 实例。


🟢 L-5: TextbookImporter 使用 print() 而非 logging

文件: backend/services/textbook_importer.py


🟢 L-6: Nginx 无 HTTPS 配置

文件: nginx/nginx.conf — 仅监听 80 端口


🟢 L-7: main.py 使用 sys.path.insert

sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))

允许无 backend. 前缀的导入,但在不同工作目录运行时会崩溃。


6. LingFlow 启用分析

6.1 当前状态

LingFlow 是灵知系统的教材处理流水线,包含以下组件:

组件 文件 行数 状态
自动处理器 textbook_processing/autonomous_processor.py 962 ✅ 输出路径已修复
工作流引擎 textbook_processing/workflow.py 808 ⚠️ step4/step5路径未修复
深度目录解析 textbook_processing/deep_toc_parser.py 518 ✅ 可用
教材服务 services/textbook_service.py 306 ✅ 可用
API端点 api/v1/textbook_processing.py 295 ✅ 受API Key保护
上下文压缩 services/compression.py 528 ✅ 可用

6.2 LingFlow 数据流

PDF教材 → autonomous_processor.py → TOC提取(deep_toc_parser) → 文本分段 → 结构化数据
                                              textbook_service.py → 入库到 PostgreSQL
                                              vector.py(桩代码) → 生成"嵌入"(SHA-256哈希)
                                              bm25.py(jieba分词) → 关键词索引 ✅ 已修复
                                              hybrid.py → RRF混合搜索(向量部分不可信)

结论: LingFlow 的处理流水线(PDF → 结构化数据)基本可用,但 step4/step5 路径未修复检索环节的向量部分完全不工作

6.3 启用 LingFlow 的阻塞项

  1. ~~路径更新~~ — ✅ step3 已修复,❌ step4 (workflow.py:508) 和 step5 (workflow.py:577) 未修复
  2. ~~中文分词~~ — ✅ 已集成 jieba + 自定义词典
  3. 嵌入服务 — ❌ 向量搜索仍为桩代码
  4. 认证激活 — textbook-processing 端点有 API Key 保护,可独立使用

7. 审计发现汇总表

# 严重性 问题 文件:行号 修复工作量
C-1 🔴 CRITICAL 向量搜索为桩代码 services/retrieval/vector.py:79-95 大(需集成嵌入模型)
C-2 🔴 CRITICAL 认证系统未启用 main.py:49-67, auth/ 中(代码已写好,需接线)
C-3 🔴 CRITICAL SQL注入(f-string) common/db_helpers.py:98-103 中(重构分页函数)
C-4 🔴 CRITICAL LingFlow step4/5路径未修复 workflow.py:508-509, 576-577 小(改路径)
H-1 🟠 HIGH Config单例无锁 config/__init__.py:88-101 小(加threading.Lock)
H-2 🟠 HIGH ServiceManager单例无锁 service_manager.py:315-328 小(加threading.Lock)
H-3 🟠 HIGH Redis URL双源冲突 config/redis.py:21-24, 87-91 中(统一URL来源)
H-4 🟠 HIGH 健康检查泄露错误 lifespan.py:154-159, db_helpers.py:201-205
H-5 🟠 HIGH DB池大小硬编码 database.py:28-34
H-6 🟠 HIGH Triple连接池 多个文件 中(重构)
H-7 🟠 HIGH 写入端点无认证 多个API文件 依赖C-2
M-1 🟡 MEDIUM aioredis过时API monitoring/health.py:262-263
M-2 🟡 MEDIUM 模块级可变全局 search.py:23, reasoning.py:22-24
M-3 🟡 MEDIUM 限流client_ip硬编码 gateway.py:85
M-4 🟡 MEDIUM 任务ID时间戳冲突 textbook_processing.py:152, 218
M-5 🟡 MEDIUM RBAC init中create_task rbac.py:522
M-6 🟡 MEDIUM 缓存端点泄露异常 health.py:119,137,161,192,211
M-7 🟡 MEDIUM nginx无body大小限制 nginx/nginx.conf
M-8 🟡 MEDIUM Dockerfile --reload Dockerfile:32
M-9 🟡 MEDIUM 配置字段重复 lingzhi.py vs database.py
M-10 🟡 MEDIUM LIKE通配符注入 db_helpers.py:135
M-11 🟡 MEDIUM postgres-exporter端口错 docker-compose.yml:198
M-12 🟡 MEDIUM Config模块级加载 config/__init__.py:~137
M-13 🟡 MEDIUM 双重限流系统 gateway.py + middleware.py
M-14 🟡 MEDIUM 默认密码弱 docker-compose.yml
L-1 🟢 LOW 备份文件 多个
L-2 🟢 LOW 监控无测试 monitoring/
L-3 🟢 LOW 未使用模块 多个
L-4 🟢 LOW ES未使用 docker-compose
L-5 🟢 LOW print代替logging textbook_importer.py
L-6 🟢 LOW 无HTTPS nginx/nginx.conf
L-7 🟢 LOW sys.path hack main.py

统计: 4 CRITICAL / 7 HIGH / 14 MEDIUM / 7 LOW = 32 项发现


8. 修复优先级路线图(Phase 7-12)

Phase 7: 安全加固(3-4小时)⭐ 优先

目标: 消除直接的SQL注入和错误泄露

  • [ ] C-3: 重构 db_helpers.py:fetch_paginated() — 使用白名单验证 query 参数
  • [ ] H-4: 修复 lifespan.py:158db_helpers.py:203 — 通用错误消息 + 日志记录
  • [ ] M-6: 修复 health.py 5处 str(e) 泄露 — 通用错误消息
  • [ ] M-10: 修复 db_helpers.py:135 — LIKE通配符转义
  • [ ] M-11: 修复 docker-compose.yml:198 — postgres-exporter 端口改为 5432

Phase 8: 认证系统激活(3-4小时)

目标: 保护所有API端点

  • [ ] C-2: 在 main.py 中添加 AuthMiddleware
  • [ ] 为写入端点添加 get_authenticated_user 依赖
  • [ ] 为读取端点添加可选认证(API Key 或 JWT)
  • [ ] M-5: 修复 rbac.py:522 — 改为显式异步初始化
  • [ ] 补全 requirements.txt 中缺失的 cryptography, pyjwt

Phase 9: 配置与单例安全(2-3小时)

目标: 消除竞态条件和配置冲突

  • [ ] H-1: config/__init__.py:92get_config() 改用 threading.Lock
  • [ ] H-2: service_manager.py:318get_service_manager() 改用 threading.Lock
  • [ ] H-3: config/redis.py:87get_redis_url() 优先使用 REDIS_URL
  • [ ] H-5: database.py:28 — 从配置读取池大小
  • [ ] M-9: 清理 LingZhiConfigDatabaseConfig 的重复字段
  • [ ] M-12: Config 改为懒加载

Phase 10: LingFlow 完整启用(2-3小时)

目标: 让 LingFlow 全流水线可运行

  • [ ] C-4: 修复 workflow.py:508-509 — step4 的 sys.path.insert
  • [ ] C-4: 修复 workflow.py:576-577 — step5 的 sys.path.insert
  • [ ] 端到端测试 LingFlow 流水线(PDF → 入库)
  • [ ] M-4: textbook_processing.py:152,218 — 任务ID改用 uuid4

Phase 11: 连接池统一 + 清理(2-3小时)

目标: 消除冗余连接

  • [ ] H-6: 移除 API 文件中的直接 init_db_pool() 调用
  • [ ] 统一使用 app.state.db_pool
  • [ ] 移除 DI 中弃用的 _db_pool
  • [ ] M-7: nginx 添加 client_max_body_size 100M
  • [ ] M-8: Dockerfile 移除 --reload
  • [ ] L-1: 清理备份文件

Phase 12: 向量嵌入集成(4-8小时)

目标: 替换桩代码,实现真正的语义搜索

  • [ ] C-1: 选择并集成嵌入模型
  • [ ] 实现真实的 embed_text()embed_texts()
  • [ ] 实现真实的 search_by_vector()
  • [ ] 对已有文档重新生成嵌入
  • [ ] 更新混合搜索权重

决策点

以下决策需要您的输入:

1. 嵌入模型选择

  • BGE-M3 (BAAI): 多语言,支持中文,需要本地 GPU 或远程 API
  • text2vec-large-chinese: 中文优化,可本地部署
  • OpenAI embeddings: 需要 API 密钥,简单集成但依赖外部服务
  • DeepSeek API: 系统已配置 DeepSeek,可以复用

2. 认证策略

  • 全面激活 JWT+RBAC: 使用已构建的完整认证系统
  • 仅 API Key: 更简单,适合内部系统
  • 渐进式: 先 API Key,后 JWT

3. Elasticsearch 利用

  • 系统已部署 ES(tcm-elasticsearch),是否用于 BM25 替代内存索引?

审计结论: 灵知系统的架构设计合理,代码量充足(~14,000行),基础设施完善。Phase 1-6 已修复路径遍历、API密钥保护、LingFlow step3路径、jieba分词集成、Redis缓存修复等问题。当前 4 个 CRITICAL 阻塞问题:向量搜索为桩代码(C-1)、认证未启用(C-2)、SQL注入(C-3)、LingFlow step4/5路径未修复(C-4)。建议按 Phase 7-12 路线图逐步修复,优先处理 Phase 7(安全加固)和 Phase 8(认证激活),因为这两项投入产出比最高——代码已写好,只需接线。


附录 A: 关联文档索引

文档 内容 与本报告关系
COMPREHENSIVE_SECURITY_AUDIT_REPORT.md 安全专项审计(基于 main_optimized.py 互补。该报告分析了简化版主文件,部分发现已在本报告中覆盖
SECURITY_RESOURCE_EMERGENCY_RESPONSE_PLAN.md 安全×资源紧急响应计划(72小时加固方案) 互补。覆盖容器资源限制、监控告警、应急恢复
ROOT_CAUSE_ANALYSIS_20260330.md 高资源占用根因分析(内存96%危机) 前置。资源问题已通过磁盘清理和容器限制缓解
OPTIMIZATION_ROADMAP_20260330.md 基础设施优化路线图 互补。聚焦基础设施层,本报告聚焦应用代码层
LINGFLOW_VALUE_CREATION_ANALYSIS_20260330.md LingFlow战略转型分析(AI编码工具增强引擎) 战略层。定义了LingFlow的产品方向和技术路线
ANALYSIS_SUMMARY.md 分析汇总 综合摘要

附录 B: main_optimized.py 审计补充

系统存在一个独立的简化版入口文件 backend/main_optimized.py(~220行),与主入口 main.py(~83行)并行存在。该文件在 COMPREHENSIVE_SECURITY_AUDIT_REPORT.md 中被重点分析。以下是该文件的额外发现:

B-1: 并行入口文件造成混淆

  • main.py 是当前 docker-compose.yml 启动的入口(通过 CMD 覆盖)
  • main_optimized.py 是一个独立的简化版入口,自带路由和数据库逻辑
  • 两者注册不同的中间件和路由,如果错误启动 main_optimized.py,安全配置不一致

B-2: main_optimized.py 的安全改进(相对于 main.py

改进项 main.py main_optimized.py
CORS 配置 已修复为白名单(Phase 1) 已使用白名单 + ALLOWED_ORIGINS 环境变量
硬编码密码 使用 env var(无默认值) 正确抛出 ValueError(无默认值)
裸异常 存在 已修复为具体异常类型

B-3: main_optimized.py 的遗留问题

  • stats 端点使用 asyncio.gather() 但文件底部 if __name__import asyncio(运行时错误)
  • LIKE 通配符未转义(与 db_helpers.py:135 相同问题)
  • 无认证保护(与 main.py 相同)
  • 单文件连接池(get_db() 中的全局 pool)与主系统连接池无关

B-4: 建议

main_optimized.py 中的安全改进(CORS白名单、强制环境变量)应回移到主系统的 SecurityConfig 中。该文件本身可考虑删除或归档,避免混淆。