对照基准:
docs/方案计划文档管理系统技术方案.md第 5 章(安全保密措施设计)、6.5(安全性设计)、docs/方案计划文档管理系统技术方案-补充修改说明.md(三权分立、四层授权模型、门户对接认证、5.7 开发过程安全保密)。 验证范围:Python 版(backend/)、Java 版(backend-java/src/)、前端(frontend/src/),双后端逐条对齐核验。 对照日期:2026-09-07。总体结论:34 项安全设计要求中具备 20 项、部分具备 7 项、不具备 7 项。
| 编号 | 差距项 | 现状证据 | 整改方向 |
|---|---|---|---|
| G-01 | 传输加密(HTTPS)不具备 | 双版无 ssl 配置;app.run(debug=False) 无 ssl_context;JDBC 串显式 useSSL=false |
部署层引入部署单位签发证书/反向代理终止 TLS;数据库连接串按部署单位密码设施开启加密通道 |
| G-02 | 应用层信封加密 KEK/DEK 不具备 | 文件流式明文直写(uploads.py:150-156、UploadStorage.java:124-126);无字段级加密、无密钥轮换 |
本轮实施(见 2.2) |
| G-03 | 审计哈希链防篡改不具备 | 审计表无 prev_hash/record_hash 字段,写入纯 INSERT 直插,事后篡改无法被校验发现 | 迁移加列(prev_hash/record_hash)+ 写入时计算内容哈希并纳入前条摘要 + 审计链连续性校验接口 + 审计动作白名单扩充(需 Alembic/Flyway 双引擎迁移与 CHECK 白名单更新) |
| G-04 | 敏感操作二次认证不具备 | 全库无操作人登录密码复核机制(现有"文档密码锁"为资源级口令,性质不同) | 本轮实施(见 2.3) |
| 编号 | 差距项 | 现状证据 | 整改方向 |
|---|---|---|---|
| G-05 | 自动化备份机制不具备 | 无全量/增量备份脚本、无只追加不覆盖备份目录,仅 README 手工 mysqldump 建议 | 备份执行脚本(周全量/日增量)+ 备份目录只追加 + 保留策略与校验 |
| G-06 | 三权分立角色体系不具备 | 角色仅 USER/ADMIN 两档(历史 AUDITOR 已于迁移 0003 禁用);审计查询权归全体 ADMIN,未与系统管理员分离 | 需契约级设计:新增安全管理员/安全审计员角色、审计权独立、管理范围细化 |
| G-07 | 权限申请审批流不具备 | 无申请单表/接口/界面/审计动作;借阅"审批单凭证"为事后留痕,无事前申请—审批链 | 需契约级设计:申请单模型、待办流转、批准即生成借阅授权、全程审计 |
| 编号 | 差距项 | 现状证据 | 整改方向 |
|---|---|---|---|
| G-08 | JWT 有效期硬编码 2 小时(设计 1 小时) | config.py:135、JwtTokens.java:29(7200s 硬编码) |
本轮顺带实施(见 2.1) |
| G-09 | 审计导出电子表格缺失 | 双端无 audit/export/xlsx/csv 接口 | 审计看板新增导出接口(xlsx) |
| G-10 | 原始文件未按"业务类型、年月"分层 | original/{uuid}.{ext} 扁平结构 |
存储路径分层 + 存量文件迁移(可选) |
| G-11 | LibreOffice 转换进程无内存上限 | 双端仅有 60s 超时 + 信号量限流(默认 2),无进程内存限制 | 启动器/容器层 ulimit 或 Job Object 内存上限 |
| G-12 | IP 登录限制仅部门维度、ADMIN 全量豁免 | ip_entry_service.py:391-421、LoginIpService.java:24-61 |
评估是否增加按用户维度条目与 ADMIN 收敛 |
| G-13 | Java 版全局安全响应头仅在送检副本 | SecurityHeadersFilter.java(X-Frame-Options/CSP/Referrer-Policy/Cache-Control)只存在于 backend-java/src-check,运行源码 backend-java/src 无此文件,Python 版亦无对应中间件 |
将该过滤器同步至 backend-java/src,Python 版补等价中间件 |
| G-14 | LibreOfficeConverter 调试日志残留 | LibreOfficeConverter.java:245,262 以 info 级打印完整命令行 |
降级为 debug 或删除 |
| G-15 | 信封加密覆盖面补全(本轮之后) | 本轮仅覆盖 original/ 原始文件;preview/、extracted/ 目录仍为明文缓存;数据库敏感字段未加密;无密钥轮换;存量明文文件未迁移 | preview/extracted 缓存加密、审计备注等字段级 DEK、KEK 轮换命令(kekVersion 已预留)、存量明文迁移 CLI |
说明:文档级 ACL 组织授权与多操作位下线(迁移 0026/V11 借阅制收敛)、部门范围 OWN/OTHER 收敛,属既有契约有意演进,不计入差距。
DMS_JWT_EXPIRES_SECONDS(环境变量/.env,双版同名对齐),缺省 3600。backend/dms/config.py 由硬编码 7200 改为环境变量读取;Java JwtTokens 由静态常量改为随环境变量解析。.env.example 增加该项及生成说明。DMSE + kekVersion(1B) + DEK 包裹长度(4B) + KEK 包裹的 DEK + 数据密文;DEK 每文件随机 32B;GCM nonce 12B 随机。DMS_STORAGE_KEK(base64,32B),环境变量注入、不落盘;未配置时回退明文兼容模式(不加密,读取自动识别)。DMSE 头的存量明文文件按明文直接读取(无需迁移)。POST /auth/reauth:登录态提交 {password},后端 Argon2id 校验通过后签发 5 分钟 reauth 令牌(JWT,type=reauth,绑定 userId 与 authVersion——重置密码/角色变更后自动失效)。X-DMS-Reauth-Token:验签、type、userId、authVersion、有效期;缺失或无效返回 403 REAUTH_REQUIRED(附"请重新输入登录密码"语义)。PUT /users/{id}(仅当 securityLevel、roleCode/roleId、status 实际发生变化时强制);DMS_API_CONTRACT.md 升版(1.20 → 1.21),新增接口、请求头与错误码说明。