CSCTalon 项目审计报告

审计日期: 2026-08-20  |  项目: CSCTalon 客服中心数据分析决策与工作流系统
代码库: /Users/tanzk/dev/csctalon  |  最近提交: 8b61f1e (全栈审计v0.7 P0 安全修复)
A-
安全防护
C+
代码质量
F
测试覆盖
B+
运维部署

一、项目概览

维度详情
定位客服中心运营数据采集→清洗→分析→决策→闭环管理一体化平台
技术栈Vue 3 + Vite + Element Plus / FastAPI + SQLAlchemy 2.0 + Gunicorn / PostgreSQL 15 / Redis 7
代码规模后端 243 个 .py 文件 / 前端 9000+ 个 JS/TS 文件(含 node_modules) / 37 个 Alembic 迁移 / 56 张数据表
部署方式Docker Compose(4 服务: db/redis/backend/web),局域网单机部署
数据采集Playwright 浏览器自动化 + ddddocr OCR 自动登录 BMS/SCRM 平台

二、审计发现总览

做得好的方面

优秀
生产环境 fail-fast 安全校验
ENV=prod 时拒绝弱默认密码、占位符、短密钥,从源头杜绝裸奔上线
优秀
JWT 令牌吊销机制
token_version 字段实现改密/登出后即时失效,防止旧 token 继续使用
优秀
SafeStaticFiles 静态文件加固
扩展名白名单 + 路径穿越防御 + nosniff,阻断登录态泄露和存储型 XSS
优秀
上传文件 magic bytes 校验
图片上传时校验文件头魔数,防扩展名伪装攻击
优秀
Fernet 加密存储第三方凭证
BMS/SCRM 账号密码使用 Fernet 对称加密入库,非明文存储
优秀
Nginx 安全响应头完备
CSP / X-Frame-Options / nosniff / Referrer-Policy / Permissions-Policy 全覆盖
优秀
DOMPurify 前端 XSS 防护
v-html 使用前经 DOMPurify 消毒,限制允许标签和属性
优秀
登录限速防爆破
按 IP 限流(5 分钟 10 次),失败/成功均记录操作日志
优秀
.env 文件未入库
已验证 .env 未被 git 跟踪,.gitignore 配置正确

需改进的方面

P0 严重
零测试覆盖
backend/tests/ 目录为空,无任何测试用例
P1 高
超大型文件难以维护
analytics.py 8508 行 / bms_fetcher.py 3273 行 / fetch.py 1199 行
P1 高
大量裸 except 吞异常
30+ 处 except Exception: 静默吞掉错误,排查困难
P2 中
死依赖 passlib
pyproject.toml 仍声明 passlib[bcrypt],但代码已改用 bcrypt 直调
P2 中
前端无 TypeScript
全部 .vue/.js 为纯 JS,缺少类型约束,重构风险高
P2 中
限速为进程内内存
多 worker 部署时限速失效(当前 -w 1 规避了此问题)
P2 中
无 CI/CD 流水线
无自动化构建/测试/部署流水线配置文件
P3 低
CONFIG_ENCRYPTION_KEY 与 JWT 耦合
加密 key 默认从 JWT_SECRET_KEY 派生,轮换 JWT 会导致凭证解密失败
P3 低
前端大组件
SyncDashboard.vue 2010 行 / Today.vue 1816 行,应拆分

三、详细审计

3.1 架构与配置

检查项状态说明
目录结构合规backend/web/docs/data 分层清晰,职责分明
.gitignore合规.env / uploads / 样本数据 / 日志均正确忽略
.env 未入库合规git ls-files 验证 .env 未被跟踪
.env.example 模板合规含占位符和安全注释,未暴露真实密钥
.gitleaks.toml合规已配置密钥泄露扫描规则
Docker Compose 健康检查合规db/backend 均有 healthcheck,web depends_on healthy
端口暴露合规DB/Redis 仅绑定 127.0.0.1,仅 80 对外
日志轮转合规json-file 10m×3 轮转 + 后端 RotatingFileHandler
依赖锁定需改进后端用 ≥ 版本范围非精确锁定;前端有 package-lock.json
CI/CD缺失无 .github/workflows / .gitea/workflows 等 CI 配置

3.2 后端代码质量

检查项状态说明
分层架构良好models / services / api / core / schemas / middleware 分层清晰
SQLAlchemy 2.0 用法良好使用 select() 新风格,无字符串拼接 SQL(仅 debug 脚本有 f-string SQL)
SQL 注入风险无风险生产代码全部使用 ORM 参数化查询
eval/exec 使用无未发现 eval/exec/os.system 调用
Ruff lint已配置line-length=100, select E/F/I/W
文件大小超标analytics.py 8508 行、bms_fetcher.py 3273 行严重超标
异常处理需改进30+ 处裸 except Exception 静默吞错
测试覆盖零覆盖tests/ 目录为空,pytest 已在 dev 依赖但无用例
死依赖存在passlib[bcrypt] 仍在 pyproject.toml 但代码未使用
Dockerfile 重复安装冗余Dockerfile 内联 pip install 与 pyproject.toml 重复,未用 pip install -e .

3.3 前端代码质量

检查项状态说明
Vue 3 Composition API良好Pinia store 使用 setup 语法
路由懒加载良好全部路由使用动态 import() 按需加载
路由守卫良好三层权限: admin / manager / roles 白名单
Axios 拦截器良好统一 token 注入 + 401 自动登出 + 错误提示
XSS 防护良好DOMPurify + escapeHtml 双重防护
TypeScript缺失全项目纯 JS,无类型约束
ESLint/Prettier缺失无 lint/format 配置文件
组件大小超标SyncDashboard.vue 2010 行 / Today.vue 1816 行
Token 存储可接受localStorage 存储(XSS 风险,但 CSP 已缓解)

3.4 数据库与数据层

检查项状态说明
模型数量完整56 张表,覆盖全业务域
SCD Type 2 历史追溯良好人员分组/专项变更历史可追溯
Alembic 迁移良好37 个版本,单一 head(已 merge),启动自动 upgrade
连接池配置良好pool_pre_ping + keepalive + pool_recycle=1800 + pool_use_lifo
启动咨询锁良好pg_try_advisory_lock 防多 worker 重复迁移/种子
僵尸任务清理良好启动时清理 running→failed,防误判跳过同步

3.5 安全审计

检查项状态说明
密码哈希bcrypt直接用 bcrypt(非 passlib),超 72 字节拒绝而非截断
JWT 签发与校验良好HS256 + token_version 吊销 + sub 整数校验防 500
登录限速已实施5 分钟 10 次/IP(内存滑动窗口)
CORS 配置受限仅允许 localhost/127.0.0.1,allow_credentials=True
静态文件安全加固SafeStaticFiles: 白名单扩展名 + 路径穿越防御 + nosniff
上传校验加固扩展名白名单 + magic bytes 校验 + 路径穿越防御
凭证加密存储FernetBMS/SCRM 凭证 Fernet 加密入库
CSP / 安全头完备CSP + X-Frame-Options + nosniff + Referrer-Policy + Permissions-Policy
v-html XSS 防护DOMPurifymarked + DOMPurify 消毒,限制允许标签/属性
微信扫码认证已加固申请者角色限制(防提权)+ prod 拒绝 mock openid
X-Forwarded-For 取值正确取末段(反代追加的真实 IP),非首段(可伪造)
500 异常处理良好全局 handler 记录完整 traceback 到日志,prod 不暴露堆栈
操作日志审计完备POST/PUT/PATCH/DELETE 全记录,含用户/IP/操作类型
改密验旧密码良好用户改自己密码需验旧密码(防会话劫持后锁户)
限速多 worker 兼容潜在风险内存限速,多 worker 下各自计数(当前 -w 1 规避)
加密 key 耦合潜在风险CONFIG_ENCRYPTION_KEY 默认从 JWT_SECRET_KEY 派生

四、改进建议优先级

P0 — 立即行动

P0
建立测试体系
现状: tests/ 目录完全为空,pytest 已在 dev 依赖中但无用例。
建议: 至少为核心模块编写测试:认证流程(登录/登出/改密)、analytics 关键计算逻辑、数据同步 upsert 逻辑。使用 pytest + httpx AsyncClient 做集成测试,目标覆盖核心路径 60%+。

P1 — 短期改进(1-2 周)

P1
拆分超大文件
analytics.py(8508 行)按业务域拆分为 analytics/refund.py、analytics/complaint.py、analytics/reception.py 等;bms_fetcher.py(3273 行)按功能拆分为 fetcher/、parser/、auth/ 等。目标单文件不超过 800 行。
P1
清理裸 except 异常处理
30+ 处 except Exception: 静默吞错。至少应加 logger.warning() 或 logger.debug() 记录被吞掉的异常,避免出现"功能不工作但日志里什么都没有"的排查惨案。
P1
清理死依赖
从 pyproject.toml 和 Dockerfile 中移除 passlib[bcrypt](代码已直接使用 bcrypt 库)。Dockerfile 内联 pip install 改为 pip install -e . 统一从 pyproject.toml 安装,消除双重维护。

P2 — 中期改进(1 个月内)

P2
引入 TypeScript
逐步将前端 .vue/.js 迁移到 TypeScript,优先改造 API 层和 store 层,利用 Vue 3 + Vite 的 TS 原生支持。
P2
添加 ESLint + Prettier
前端缺少代码规范工具,建议配置 eslint-plugin-vue + @typescript-eslint + prettier。
P2
建立 CI/CD 流水线
配置 Gitea Actions 或 GitHub Actions:lint → test → build → docker push,每次 PR 自动检查。
P2
限速迁移至 Redis
将登录限速从进程内内存改为 Redis 实现,为未来多 worker 扩展做准备。代码注释中已标注此为 M5 待办。

P3 — 长期优化

P3
CONFIG_ENCRYPTION_KEY 独立化
生产环境显式设置独立 CONFIG_ENCRYPTION_KEY,解除与 JWT_SECRET_KEY 的派生耦合。.env.example 中已提示但默认留空。
P3
前端大组件拆分
SyncDashboard.vue(2010 行)和 Today.vue(1816 行)按功能区域拆分为子组件,提高复用性和可维护性。
P3
依赖版本精确锁定
后端 pyproject.toml 使用 == 精确锁定版本或生成 requirements.lock,确保构建可复现。

五、审计结论

CSCTalon 是一个功能完整、安全意识较强的内部系统。从 git 历史可见团队已进行过多轮安全加固(v0.7 P0 修复、安全加固专项),核心安全机制(认证、授权、加密、限速、安全头、XSS 防护)均已到位且实现质量较高。


最大风险点是零测试覆盖——56 张表、8500 行分析引擎、3273 行数据抓取器,全部没有自动化测试保护,任何重构或修改都存在引入回归的高风险。建议优先建立核心路径的集成测试。


最大技术债是超大文件(analytics.py 8508 行)——这会严重拖慢后续开发效率和代码审查质量,建议尽快按业务域拆分。


整体而言,项目在安全性和架构设计上表现优秀(A-),在代码质量和工程规范上有较大改进空间(C+),测试覆盖需要紧急补齐(F),运维部署配置合理(B+)。