fix(security): remediate telecom compliance findings

This commit is contained in:
2026-07-28 11:33:05 +08:00
parent c38a9e74ad
commit 29e4e4a804
17 changed files with 293 additions and 72 deletions
+38
View File
@@ -0,0 +1,38 @@
# 企迹(qiji)代码审查报告
## 结论
**结论:不符合上线条件。** 仓库存在可直接导致身份伪造、基础设施未授权访问和对象存储越权读取的高风险问题;在整改并完成复测前,不应部署到中国电信生产环境。
审查基线为 `c38a9e7`2026-07-28 拉取),审查依据为工作区提供的《中国电信软件研发规范(修订版)》相关分册。结论为代码与仓库材料审查结果;未取得 Git 平台分支保护配置、生产环境网络策略、制品库、扫描平台和测试平台的实际证据,相关项均不能视为已合规。
## 发现的问题
| 优先级 | 问题 | 规范依据 | 证据与影响 | 整改建议 |
|---|---|---|---|---|
| P0 | 生产默认密钥与弱口令,且数据库、MinIO 和控制台直接映射宿主机端口 | 安全分册 2.4(须更换默认口令);3.1.4【强制】(禁止硬编码敏感信息) | `backend/app/config.py` 中 JWT 密钥、数据库密码和 MinIO 密钥均有可预测默认值;`docker-compose.yml` 使用 `postgres/postgres``minioadmin/minioadmin`,并开放 5432、9000、9001。Compose 未覆盖 `SECRET_KEY`,因此按默认启动时攻击者可签发任意角色 JWT。 | 删除所有生产默认值;启动时校验密钥长度、随机性和非默认值;使用受控密钥管理/注入;数据库和 MinIO 仅加入内部网络,不发布端口;轮换已暴露的凭据。 |
| P1 | 任意登录用户可为任意对象键签发下载 URL(水平越权) | 安全分册 3.3.3.10【强制】(对象操作的 SQL/查询须附带当前用户身份条件) | `backend/app/api/upload.py``/download-url` 直接接收 `object_key` 并签发 1 小时 URL,未查询照片所属拜访记录、客户权限或对象键前缀。已知或猜测键名的用户可下载其他员工照片。 | 不接受裸 `object_key`;由照片所属业务记录 ID 查询对象,按当前用户角色、所属人和客户授权校验后签发;对象键应使用完整 UUID 前缀并记录访问审计。 |
| P1 | 系统配置读取接口没有鉴权 | 安全分册 3.3.3.9【强制】(管理 URL 必须校验当前用户权限) | `backend/app/api/system_config.py``GET /api/system-config` 未注入 `get_current_user` 或角色校验,会返回全部配置,包括可包含业务提示词等内部配置。 | 至少要求已认证用户;建议仅 director 可读管理配置,并对可公开的配置采用明确白名单。 |
| P1 | 企微绑定流程信任客户端传入的 `wecom_userid`,且写入时未校验唯一性 | 安全分册 2.1.8(避免未经授权访问会话状态);3.3.3.9【强制】 | `POST /api/auth/bind-wecom` 使用 `req.wecom_userid` 优先于受保护的绑定状态;`services/auth.py` 直接赋值并提交。攻击者可将自己的 Casdoor 账户绑定到任意企微 ID,形成账号关联劫持/覆盖风险。 | 仅接受服务端保存、一次性、短时有效且与发起人绑定的随机令牌;服务端从令牌取企微 ID;数据库加唯一约束,并在绑定/解绑时保留安全审计。 |
| P2 | 直传上传未实际限制文件类型或验证内容 | 安全分册 3.3.4.9【强制】(扩展名白名单、不可直访目录、系统命名、图片处理、上传日志) | `/presigned-url` 接收但未使用 `filename``content_type`;对象固定以 `.jpg` 结尾,预签名 PUT 后服务端不检查 MIME、魔数、大小、恶意内容或上传结果。对象存储由独立端口暴露。 | 采用受控后端上传/隔离桶,限制大小和白名单;校验文件魔数并转码图片,病毒扫描后再移入正式桶;记录上传审计。保留现有的系统生成键名优点。 |
| P2 | 日志可能泄露用户内容和第三方认证响应 | 安全分册 3.1.1【强制】(日志不得保存口令、密钥和其他敏感数据);3.3.3.11【强制】(未经验证输入不得写日志) | `backend/app/api/wecom.py` 记录企微发送人和完整消息正文;`services/auth.py` 在认证失败时记录响应正文或完整 token 数据。周报/客户信息可能含个人或经营敏感内容。 | 使用结构化日志、字段白名单和脱敏;禁止记录 token、企微正文及认证响应体;限制日志访问并设置保留期限。 |
| P2 | 缺少生产部署与变更可追溯材料 | 部署管理分册 2.2.1、2.2.2、2.3、2.5、2.6 | 仓库无上线测试报告、版本—制品—代码版本映射、部署/回退/数据备份方案、审批记录或部署验证用例;`docker-compose.yml``--reload` 和源码挂载启动后端,不是可审计的生产部署方式。 | 建立发布包:版本 Tag、制品摘要、SBOM、测试报告、部署/回滚/备份方案、审批和验证记录;生产镜像使用固定版本/摘要,不使用开发热重载或源码挂载。 |
| P2 | 未发现自动化测试、质量扫描或 CI/CD 流水线 | 测试管理分册第 4 章;流水线管理分册 3.2、3.3 | 仓库未发现 `tests`/`test` 目录或测试脚本;前端 `package.json` 只有 dev/build/preview;无 GitHub/GitLab/其他 CI 配置。缺少单元、集成、系统测试及安全/质量扫描的可追溯证据。 | 为关键鉴权、上传、企微绑定和数据隔离补充单元及 API 集成测试;在 MR 和合入时强制执行测试、SAST、依赖/SBOM 扫描、构建和制品上传;设定测试准入/准出与缺陷闭环。 |
| P3 | 仓库内提交 Excel 二进制文件,且缺少发布 Tag 证据 | 代码管理分册 4.3【C0】(不得提交 xls/xlsx 等文件);5.1【C1】(发布版本必须打 Tag) | 根目录包含 `weekly_report_template.xlsx``weekly_report_template (2)_补全.xlsx`。当前 Git 历史未见发布 Tag。README 和根 `.gitignore` 已存在,符合代码管理分册 2.3 的基础要求。 | 将模板转入受控制品/文档库,或经规范例外审批后保存;创建语义化发布 Tag,并确保 Tag、制品版本和发布说明一致。 |
## 已验证情况
| 检查 | 结果 |
|---|---|
| 后端语法编译 | 通过:`python -m compileall backend/app` |
| 前端生产构建 | 通过:`pnpm run build`(有第三方注释与单包体积超过 500 KB 警告) |
| 代码基础材料 | README、`.gitignore``.env.example`、Dockerfile 与 Compose 文件均存在 |
| 访问控制抽样 | 拜访、日纪要等 CRUD 对 manager 的所属人校验已实现;但对象下载和配置读取破坏了整体最小权限原则 |
## 整改优先顺序
1. 立即轮换所有默认/已提交凭据,停止暴露 PostgreSQL、MinIO API 与控制台端口,并禁止默认 JWT 密钥启动。
2. 修复对象下载授权和企微绑定状态校验,补充安全审计日志。
3. 建立上传隔离、文件校验与脱敏日志机制。
4. 建立受保护分支、合并评审、测试/SAST/依赖扫描流水线及制品版本追溯。
5. 按部署管理分册准备测试报告、回滚方案、审批和上线验证材料后再申请上线。