Scert/doc/全面审查测试与优化记录.md

152 lines
12 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 全面审查、测试与优化记录
> 2026-09-27 证据索引:当前 44 项整改的逐项范围、命令、实机步骤和复审字段见《整改任务规格与验收约定》及四份分级规格;实际进展以《Scert整改任务执行清单》为准。本文历史结果须按当时源码与环境解释。
> 2026-09-27 范围调整:以下为历史审查证据。当前正式测试范围仅为 Web 和 Windows/Linux 服务端;历史桌面模块测试记录保留,但不再作为交付目标或生产门禁。当前任务状态见《Scert整改任务执行清单》。
## 一、范围与需求确认
日期:2026-09-15。本轮从北京时间 20:47 开始,承接“全面审查、测试、优化”的要求。
本轮按既有需求执行,不扩大测试授权:
- 保留多用户;新安装优先阿里云,既有服务商配置保持兼容。
- 管理部署环境为 `47.108.78.12`;`8.137.23.95` 仅作为推送测试目标,不能混用。
- 禁止修改 `pcux.cn` 及其子域的 DNS、证书、私钥和站点;不重载共享 Nginx。
- 自动化测试使用各自隔离的临时数据,不清空现有业务数据库。
- 不调用真实 RAM API,不执行全局域名发现,不把历史可见范围当成当前可写授权。
- 不删除已有构建、补丁、工作区文件,不把含凭据的辅助脚本加入 Git。
- 中文文件通过补丁修改;分阶段中文提交、显式暂存、推送并验证。
## 二、任务清单
| 状态 | 任务 |
| --- | --- |
| `[✓]` | 恢复任务、核对工作区及两台主机边界 |
| `[✓]` | 桌面模块同步后端 SSH 安全依赖,恢复只读模块测试 |
| `[✓]` | 认证和初始化跨源写请求防护及回归 |
| `[✓]` | 同步长操作的有限上下文、响应期限及真实套接字回归 |
| `[✓]` | 初始化锁粒度优化及并发提交回归 |
| `[✓]` | 前端 DNS 旧响应、输入失效、过期令牌和卸载竞态修复 |
| `[✓]` | 续期及阿里云报告嵌套错误脱敏 |
| `[✓]` | 认证状态容量、过期回收、并发退出补强及最终全量复核 |
| `[✓]` | 默认阿里云与最小权限提示优化;前端 12 项测试通过 |
| `[✓]` | 最终全量测试、竞态检测、静态检查及漏洞复扫 |
| `[✓]` | 源码提交推送、远程 HEAD 核对、独立干净副本依赖安装及前端测试 |
| `[!]` | 最新 Linux 发布包:PowerShell 执行策略拒绝发布脚本,未生成新归档 |
| `[!]` | 实际浏览器页面验收:本地服务启动被执行策略拒绝,未绕过 |
| `[!]` | 真实初始化、正式 ACME、受控业务推送及生产准入 |
## 三、复现与修复
### 1. 跨源登录、退出与初始化写入
原登录与退出接受跨源 `Origin` 或 `Referer`,并允许 `text/plain` 携带 JSON。跨源回归在修复前返回 200。仅限制初始化请求来自回环地址,也不能替代浏览器来源校验。
登录、退出、初始化提交和初始化 DNS 测试加入来源中间件;跨源返回 403,不设置或清除 Cookie,也不删除已有会话。同源和无来源头的既有 CLI/API 访问保持兼容。
### 2. 长操作完成后客户端却读到 EOF
普通 HTTP 写期限为 30 秒,而 DNS 等待和证书工作流明显更长。使用真实回环套接字,把普通写期限缩短为 50 毫秒、模拟 DNS 工作流延迟 150 毫秒,原实现稳定出现 EOF。
增加按路由配置的长操作中间件:DNS 使用其验证期限,证书操作上限 30 分钟,初始化外层 12 分钟。通过 `ResponseController` 调整响应写期限,并留出 2 分钟处理清理、回滚和结果序列化。普通请求的超时保护不变。新增取消后的明确响应测试。
**反向代理仍必须单独设置足够的读响应期限**。服务器放宽写期限不会自动改变 Nginx、负载均衡或客户端超时;本轮未修改远程代理配置。
### 3. 初始化阻塞所有配置读取
初始化原来在证书签发期间持续持有配置写锁。改为专用初始化互斥锁,加上开始和结束时的短配置锁。并发初始化返回 409;在模拟签发阻塞期间,状态请求仍可返回。
### 4. DNS 输入与旧响应串线
初始化及系统设置存在旧请求覆盖新输入、新结果的问题;系统设置对过期令牌和新增凭据检查不足。最初六个新增测试在修复前失败。
采用请求代次与同步输入监听,只有当前代次可更新结果、错误和加载状态。输入变化、关闭设置、组件卸载均使在途结果失效。新增配置必须有未过期的服务端验证令牌;未修改已保存 DNS 配置时仍可保存其他设置。
测试直接运行真实 Vue 组合式逻辑、监听和生命周期,模拟网络,不引入新 npm 依赖。**这些测试不是页面渲染或真实云 API 验收。**
### 5. 嵌套错误泄露
原 `RenewalReport.Errors`、阿里云报告 `Diagnosis` 和逐域 `Error` 能把底层错误带回客户端。新增哨兵错误测试在修复前失败。
保留失败数量、域名及写入和清理状态,返回安全中文诊断;未知 SDK 错误、受保护凭据读取错误不再直接拼接到响应。写入成功但清理失败仍明确显示 `writable=true`、`cleanup=false`、`verified=false`,不把脱敏误做成成功。
### 6. 登录状态长期增长和并发退出
三个新测试证明:过期且不再访问的会话未清理;随机账号可持续增加限流表;大体积账号输入直接留在限流键中。
改为:
- 新登录前回收过期会话,认证会话和失败登录表各设 4096 项上限。
- 限流表按请求触发、至少间隔一分钟回收过期项,不提前解除有效封禁。
- 账号规范化后散列为固定长度键,避免存储整段大输入。
- 会话表满时返回 503,不踢出有效用户;限流表满时未知键返回 429,不能悄悄绕过限制。
- 用户校验返回后再次检查会话存在性,避免已经完成的退出被旧刷新请求继续使用。
- 增加会话容量恢复和暂停账号查询期间并发退出的回归。
容量上限是内存保护,不是完整抗攻击方案。高并发认证、全局容量耗尽时正常用户可用性,以及可信代理下的来源限流,还需独立负载与攻击流量验收。
### 7. 阿里云入口与提示
全新初始化默认 `aliyun`,已保存的服务商仍保留。权限拒绝提示不再建议直接授予 `Action: alidns:*`,而是核对实际托管区并按失败动作补充必要权限,不扩大至所有域名。
这不代表整个产品已完成阿里云专用化。其他服务商的 UI 和兼容实现未删除。
## 四、已收取的验证证据
- 第一阶段后端全量测试、全量竞态检测、`go vet` 和模块校验通过;语句覆盖率 63.9%。
- 桌面模块依赖原来在 `-mod=readonly` 下要求更新;同步 `golang.org/x/crypto v0.56.0` 后测试、静态检查、模块校验通过。
- 后端、桌面漏洞扫描均为零调用可达漏洞、零已导入受影响包。模块层仍提示 `GO-2026-5932`:未使用的 `golang.org/x/crypto/openpgp` 包,无修复版本。不能写成“依赖树完全无漏洞提示”。
- 第二阶段认证及 DNS 包测试通过,新增容量及并发测试纳入最终全量复跑。
- 前端最终 `npm test` 为 12/12,通过全依赖及生产依赖审计,均零漏洞。
- 最新产品前端生产构建通过,输出到全新 `.runtime/review-20260915-2115/install/web`,未覆盖旧产物。
- Linux 安装脚本 `bash -n`、Windows 安装脚本 PowerShell 语法解析通过;未执行安装器。
- 本地服务后台启动调用被执行策略拒绝。没有换启动方式绕过,没有继续启动浏览器,没有本轮实际页面截图或页面验收结论。
21:23 收取最终后端复跑:全量测试、全量竞态检测、`go vet`、`go mod verify`、漏洞复扫均退出零。最终语句覆盖率 **64.0%**,HTTP 包 **70.6%**。桌面模块针对最新后端的只读模块测试、静态检查、模块校验也全部通过。
中间一次容量测试误用了“必须登录成功”的旧测试辅助函数,把预期 503 当作失败;已改为直接发 HTTP 请求断言 503,再验证过期回收后登录恢复。最终结果来自修正后完整重跑,不使用失败运行的覆盖率文件。
候选提交与发布包结果在本文件末尾追加,以最后一次成功记录为准。
## 五、仍需整改和生产验收的项目
### 发布阻塞
1. **阿里云写探测授权边界**:`AliyunAuthorizationChecker.Verify` 仍会从目标向父级候选逐级试写。应由用户明确托管区与允许操作范围,任何父区或公共后缀都不能因自动推断而获得操作授权。现有只读 `Inspect` 已是精确托管区模式,但不等于写路径已整改。
2. **当前管理环境未完成初始化和正式 TLS**:上轮文档记载 `/readyz=503 setup_incomplete`,正式 ACME 连接超时。本轮没有远程刷新,不能当作已解决或确认当前仍然如此。
3. **新代码未实机安装验收**:需要维护窗口、完整备份、受控升级、真实初始化、浏览器 HTTPS/SNI、正式证书链及回滚演练。
4. **真实业务推送未验收**:隔离 SSH/SFTP 事务测试不等于已有业务服务的实际证书读取、配置校验和授权 reload;`pcux.cn` 禁止修改仍然有效。
### 后续安全与质量工作
- 会话有效性校验对缺少 `UserID` 或 `PasswordHash` 的内部会话仍有兼容分支;真实登录会填写这两项,多个旧测试直接注入不完整会话。应先改测试夹具,再使生产分支严格失败关闭,不能把其当前状态称作完整认证审计通过。
- 长请求需要反向代理和实际客户端超时验证;后续宜评估异步任务接口,而不是继续提高所有请求的全局超时。
- 多用户、高并发、容量饱和与长时间运行尚未压力验收。
- Windows Service、Wails 安装包、ACL、MySQL 和真实防火墙链路需要各自目标平台验收。
## 六、结论
本轮完成了多项可复现缺陷修复和自动化回归,提升了发布候选质量;**不构成“全部开发完成”或“生产验收通过”**。尤其是用户强调的部分域名授权边界,应作为正式写入和生产准入前的优先整改项,而不是用全量测试通过替代。
## 七、最终交付与执行阻塞
21:25 左右完成以下复核:
| 项目 | 结果 |
| --- | --- |
| 第一阶段安全修复提交 | `00ea12cbd99900626b15870131869a10c3049d2c`,已推送 |
| 最新产品源码提交 | `667f76924e6d2cb4646ad7207768664c03b95d54`,已推送且远程 HEAD 一致 |
| 独立源码副本 | 系统临时目录 `scert-review-source-667f769-2125`,全新 Git 克隆,工作区干净 |
| 副本依赖及测试 | `npm ci`、`npm test` 通过,12/12,依赖审计零漏洞 |
| 最新 Linux 发布归档 | 未生成,不能提供或编造新归档 SHA256 |
| 远程部署 | 本轮未连接两台远程主机、未安装本轮代码 |
| 本地浏览器服务 | 启动被执行策略拒绝;复核 15200、15201 均无监听 |
| 原文件及旧产物 | 均保留,没有清空业务数据库或删除用户文件 |
发布脚本在独立副本中正常调用时,被 PowerShell 拒绝,错误为 `PSSecurityException / UnauthorizedAccess`,提示系统禁止运行脚本。没有改执行策略,没有设置 `ExecutionPolicy Bypass`,没有读取脚本文本重新执行或改写调用方式绕过保护。
本地服务启动调用被工具执行策略拒绝,与发布脚本的 PowerShell 策略错误是两个独立阻塞,不能声称只解决其中一个就可以完成页面与打包验收。独立副本 `npm ci` 还提示 `esbuild` 安装脚本未列入允许项;当前依赖安装和前端测试通过,但后续实际发布构建仍需按环境规范核对,不为消除告警自动扩大执行权限。
此前保留的 Linux 候选来自旧提交,不包含本轮修复。恢复发布流程后必须从上表源码提交或后续经过完整验证的新提交重新构建,检查 `source_dirty=false`、内嵌 VCS 信息、归档成员、完整校验清单和哈希,再安排受控实机验收。