Files
Aether/docs/operations/security-hardening-full-audit.md
T
elky a90d564931 fix: restore security hardening compatibility and validation
Restore authorized rule reveal, explicit full HTTP capture and retention, video task business fields, and valid payment URLs. Add opt-in credential preservation for trusted recovery, fix frontend type contracts and async races, and eliminate PostgreSQL test fixture resource leaks. Document audit coverage and successful fmt and CI-scoped Clippy checks.
2026-09-07 21:14:27 +08:00

17 KiB
Raw Blame History

安全加固全仓兼容性复核(2026-09-07)

范围与方法

  • 加固基线:579f2c7cc2026-09-04);复核时 HEADa5c3699ae。保留已有未提交的兼容性修复,不整体回退该混合提交,也不撤销后续修复。
  • 历史提交涉及 1019 个文件,其中 907 个路径仍存在,112 个已在后续重构中移除。逐路径清单见 security-hardening-audit-manifest.tsv;已移除的旧数据库适配器、未发布迁移等不凭历史清单重新引入。
  • 对复核时 Git 跟踪的 2843 个 Rust、TypeScript、Vue、JavaScript、Python、SQL 和 Shell 源文件进行清单、读取与模式扫描,并检查加固差异、后续修订及关键生产调用链。正文清空、无条件禁用、脱敏、URL 拒绝、权限与数据归属等是重点搜索模式。
  • 清单中的 heuristic_added_risk_lines 是启发式候选行数,含初始化代码和内联测试,不是 Bug 数、漏洞数或逐行人工审计完成标记。全仓扫描、模块复核、回归测试是不同的覆盖层次,不等于人工精读所有源文件,也不承诺零遗漏。
  • 判断标准:恢复管理员明确启用的功能和必要业务数据;保留未授权访问阻断、默认保护、凭据隔离和有界资源使用。不因一条旧测试要求“所有内容都为空”,就把正常功能重新禁用。

之前的规则、OAuth、full 记录及视频四类修复详见 security-hardening-compatibility-review.md。本报告只把本次扩展检查的新发现单独计数。

本次新增确认并修复的两类加固回归

1. 正文的“压缩保留”被替换成删除

涉及 crates/aether-data/adapters/postgres/src/usage/cleanup.rs

原本分为详细正文、压缩正文、请求头、计费记录等独立保留周期。加固后,详细正文清理不再压缩迁移,而是删除正文、独立 blob 与审计引用;选择条件还包含已经独立存储的正文。因此采用默认 7/30 天设置时,明确启用 full 后保存的正文也会在约 7 天后提前失去,而不是按压缩正文的 30 天保留。

修复内容:

  • 详细正文到期只处理主表中的旧内联/压缩数据,将四个方向的正文迁入独立 gzip blob,并保留 HTTP 审计引用;不选择已经迁出的正文反复处理。
  • 旧 metadata 中的正文引用按当前请求和字段校验后迁入审计表,删除旧 metadata 键,但不删除实际正文。无效、跨请求及跨字段引用不恢复。
  • 每条迁移在事务中锁定并重读来源行。正文写入或引用更新失败时回滚,不先清空原值;其他 metadata 内容保留。
  • 预览统计与实际清理选择条件一致。压缩正文到期仍删除;明确选择“立即清理正文”的操作仍执行删除,未把隐私清理功能改成永远保留。

真实 PostgreSQL 回归使用正式迁移后的 schema 与会话隔离的临时表,覆盖四个方向的内联 JSON、旧 gzip、独立 blob、旧引用迁移、外部请求引用拒绝、7/30 天区间、过期删除、重复清理幂等、显式即时删除和中途写入失败后的事务回滚。不会读取或修改业务数据库。

同时修复了该迁移路径原有的 SQL 错误:usage 表没有 updated_at 列,旧更新语句却写入它,真实 schema 下会导致迁移失败。这个错误在加固前已经存在,不混算成第三类加固新增回归

2. 合法支付会话链接的 fragment 被误拒绝

涉及 frontend/src/utils/paymentUrl.ts,调用方包括钱包充值和订阅购买。

加固把包含 #fragment 的 HTTPS 支付链接一律拒绝。支付会话链接可能依赖该片段,不能将其等同于脚本协议或 URL 内嵌凭据。现在保留原有片段、查询参数及编码,同时继续拒绝非 HTTPS、相对地址、反斜杠和 URL 用户名/密码。

对应工具函数新增会话片段和编码保留测试,危险协议及凭据注入用例继续执行。服务器端支付 API 基址的同源、TLS 和无片段限制不变;没有放宽 webhook 验签、支付金额、订单归属或实际支付状态校验。此次不进行真实扣款测试。

按模块的复核边界

模块 复核内容与处理
公共入口、认证、会话、管理令牌 核对路由分类、认证缓存刷新、跨节点撤权和令牌权限目录;保留身份头防伪、用户/管理员隔离及敏感动作的权限要求。
端点配置及编辑往返 保留前序规则原值查看、重复/嵌套规则恢复、占位符拒绝和并发编辑保护,避免只恢复显示而破坏再次保存。
普通 Provider 连接与代理 对照后续 DNS/FakeIP/SOCKS 修复,不重新引入已移除的普通 Provider 地址过滤;凭据专用连接与普通业务代理分开判断。
OAuth、SMTP、LDAP 与密钥 检查默认客户端、显式覆盖、凭据迁移与目标绑定;保留 Gemini CLI/Antigravity 兼容性恢复及既有 SMTP 修复,不撤销传输凭据隔离。
请求记录、候选诊断及保留策略 核对配置读取、采集、投影、单条/批量写入、读取和清理链路;修复本报告的提前删除,保留显式 full 及必要诊断,不把原始正文重新塞回计费主表。
视频与异步任务 保留前序提示词/展示名、签名产物 URL、Gemini 结果 URI、数据库领取字段修复;身份不可变条件、任务归属、加密文件和下载凭据隔离不撤销。
模型、调度、配额和池状态 对照模型获取、手动模型、健康摘要、候选选择、额度预留及状态流转;不回退混入该提交的订阅/计费功能。
钱包、订阅、兑换与支付 检查业务 URL 到前端跳转链路并修复 fragment 误拦;交易归属、金额、并发更新、幂等及回调校验维持原边界。
流式、WebSocket、格式转换 检查请求限制、认证头转发、取消/重定向、会话延续和正文捕获之间的关系;修正两处与恢复后的日志语义冲突的旧断言,不退回禁用功能的实现。
系统导入、导出、备份和恢复 区分交互式导入、恢复备份、回滚模式;保留加密备份、用途绑定、导入锁和凭据保留规则,不把安全导出误当作完整灾备。
数据契约、PostgreSQL 和迁移 检查脱敏投影与业务字段消费者是否矛盾;旧驱动不复活,使用真实迁移 schema 验证正文及视频的关键写入链路。
管理前端与外链 复核脱敏状态、权限显示、URL/导航校验、支付调用方,并执行全部前端测试与真实项目类型检查。
安装、更新、容器和发布流程 执行归档、链接、目录、写入目标、来源信任、compose 参数及发布供应链的隔离 Shell 测试;不运行实际部署。

“全部修复”续轮完成项

以下问题已按根因处理,不再作为上一轮的未解决清单。历史类型问题、测试夹具与辅助器缺陷不统一归因为本次加固,功能恢复也不以撤销所有保护为代价。

1. 真实前端类型检查及相关运行时缺陷

  • 修复原先 116 个文件中的 461 条类型诊断,将 npm run type-check 改为 vue-tsc -b --force --pretty false,确实检查引用的应用和工具项目,不再依赖顶层空项目的成功退出。
  • 按现有接口契约补齐响应泛型、可空字段、配置 schema、图表时间轴、用户角色、事件参数及测试夹具。保留严格检查、ES2021、未知数据边界与动态配置扩展字段,未通过 any、忽略诊断、排除测试或降低配置绕过错误。
  • 修复请求缓存和登录校验在 fetcher 同步抛错后不能正确清理 in-flight 状态的问题;失败后可按原有退避策略重试,仍隔离不同身份和旧请求。
  • 修复 Provider 余额重试的迟到响应覆盖新加载结果,以及卸载后更新状态的问题;新增回归同时覆盖合法的零余额与签到失败值,不因真假值判断隐藏正常数据。
  • 修复钱包模板中的刷新调用,并在用户密钥删除、路由配置保存等异步流程中固定操作目标,避免确认期间切换页面后作用到另一个对象。

2. 手动保留天数取了更激进的截止点

usage_cleanup_window_with_override 原来使用 max 合并截止时间,与界面“在策略内取更保守时间点”的设计相反:删除条件是记录时间早于截止点,选更晚的时间会扩大删除范围。

现改为每一保留层级分别取 min。详细正文、压缩正文、请求头、完整日志均不短于既有策略,也不短于本次手动指定天数。测试覆盖 0、5、30、180、400 天及“选中记录是原策略子集”的关系。显式立即清理模式不受此改动影响。

3. 可信原始数据库恢复可显式保留凭据

原始 JSONL 导入及数据库复制曾无条件替换密码哈希、API Key 和管理令牌,导致可信恢复/迁移也不能继续使用原凭据。新增 CLI --preserve-credentials,仅由操作者显式选择,不能由导入文件中的字段自行启用:

aether-gateway --database-driver postgres --postgres-url "$TARGET_DATABASE_URL" import --input /path/to/trusted.jsonl --preserve-credentials
aether-gateway copy --source-driver postgres --source-url "$SOURCE_DATABASE_URL" --target-driver postgres --target-url "$TARGET_DATABASE_URL" --preserve-credentials
  • 不加该参数时仍默认撤销导入的身份凭据,并在操作前给出警告;原有库函数入口也保持该默认值。
  • 显式保留时,只保留导入文件中用户密码、API Key 和管理令牌原有字段/状态;不会把原本停用的凭据重新启用。
  • 导入的登录会话仍撤销,代理隧道仍重置在线状态和代际。外键、身份归属、OAuth 绑定一致性、输入大小及事务校验不变。
  • 仅适用于可信且由操作者控制的备份/来源。目标实例须使用与来源兼容的加密配置;此开关不会解密、重新加密或重建已经丢失的值。复制链接的 TLS 默认保护不变。
  • 这是原始数据库工具的选项,不改变 HTTP 配置导入权限,也不替代已有的加密备份恢复模式。操作示例会写入指定目标,执行前须自行核对目标并备份;本轮仅在临时隔离库中验证。

真实 PostgreSQL 回归分别验证默认撤销与显式保留后的密码哈希、密钥哈希、密文和启用状态;单元回归另覆盖管理令牌、会话及隧道边界。

4. 数据库回归夹具与测试资源回收

  • 修正历史测试的超长 ID、NUMERIC/f64 解码、依赖预填充数据库的统计夹具,以及使用不在持久化契约内的 metadata 字段。使用真实 UUID、显式 SQL 类型转换、自建自清理数据和合法 trace 字段,未放宽生产 schema 或脱敏规则来迁就测试。
  • 保留现有 usage 导出时间戳以秒计的兼容契约,未因旧字段名包含 _ms 就改变导入导出单位。
  • 临时 PostgreSQL 辅助器改为 pg_ctl stop -m fast 并等待子进程退出,再清理自有目录;关闭失败时保留进程与目录的所有权,允许重试,不强杀后直接删数据。
  • 新增两个真实 PostgreSQL 回归,覆盖打开连接下四次停止/重启、数据保留、重复停止、关闭失败重试及析构清理。专项运行前后共享内存段清单未新增残留;未清除其他业务或历史进程的 IPC 资源。
  • 续轮全量回归进一步定位到迁移、回填测试各自复制的旧辅助器,同样在强杀后泄漏资源,导致后续网关测试无法初始化数据库。两份实现已合并到仅测试使用的 postgres_test_support.rs,采用相同的正常关闭与失败重试规则,另补两个回归;没有只清理环境而保留泄漏代码。
  • AETHER_REQUIRE_LOCAL_POSTGRES_TESTS=1 强制迁移、回填和共用辅助器的真实数据库用例执行,生命周期筛选结果为 63 通过、0 失败、1 忽略;该忽略项为已在隔离数据库中单独通过的导入测试。此次完整生命周期运行前后 IPC 清单一致。
  • 辅助器支持 AETHER_PG_CTL_BIN,默认查找 AETHER_POSTGRES_BIN 同目录下的 pg_ctl;初始化失败也回收本次拥有的工作目录。

验证结果

验证层 结果
Rust 工作区所有 library 与 binary 测试目标 最终 cargo test --workspace --lib --bins --locked -- --test-threads=4:65 个目标,8944 通过、0 失败、19 默认忽略;其中 41 个 library 目标 8645 通过,24 个 binary 目标 299 通过。设置 AETHER_REQUIRE_LOCAL_POSTGRES_TESTS=1,迁移/回填测试不能因环境问题静默跳过。
最终网关全量 随工作区 feature 合并执行:5124 通过,0 失败,含此前因数据库初始化失败的两项跨节点认证回归。使用仓库既有的 RUST_MIN_STACK=16777216 测试配置;不直接运行遗漏该配置的产物,也不改生产配置规避问题。
PostgreSQL 适配器全量含真实数据库回归 AETHER_TEST_DATABASE_URL=<隔离库> cargo test -p aether-data-postgres --lib --locked -- --include-ignored --test-threads=1:232 通过,0 失败,0 忽略,包含原先默认忽略的 16 项。
原始数据库导入/导出 设置独立的 AETHER_TEST_POSTGRES_URL 并执行 lifecycle::export::tests --include-ignored:18 通过,0 失败,0 忽略,包含迁移后数据库读取及两种凭据策略的真实往返。
临时 PostgreSQL 关闭/重启 aether-testkit --features postgres 的两个真实数据库专项回归均通过;四次打开连接下重启、关闭失败重试、目录与共享内存回收均已验证。
WebSocket 真实网关集成 最终重新执行 11 通过、0 失败,含跨连接继续对话、连续计费、长连接撤权、认证头隔离、未知字段透传、断开结算、额度重试和 PII 恢复。使用临时 PostgreSQL 与模拟上游。
可执行入口 299 项通过中包括网关主入口 61、隧道 185、备份恢复 CLI 10、两种 WebSocket 探针 3/4,以及压力测试种子/探针、模拟上游等入口测试。没有启动这些工具的实际生产操作。
额外入口与身份隔离集成 aether-data --test public_entrypoints 3 项、aether-gateway --test admin_unsigned_identity_headers 1 项均重新执行通过。
前端全量与构建 最终 npm run test:run:200 个测试文件、1419 项测试通过;npm run build:with-typecheck 构建通过。
类型与格式 npm run type-check 实际运行 vue-tsc -b --force --pretty false:0 错误,原先 461 条诊断均已修正;142 个改动/新增前端源码文件 ESLint 为 0 错误、0 警告。cargo fmt --all -- --checkgit diff --check 通过。
提交前 Clippy 本地按 .github/workflows/rust-ci.yml 的 Gateway、Data、其余工作区三组范围执行,均使用 --locked-D warnings,全部通过;未关闭或放宽 lint 规则。
安装/发布脚本 10 份隔离 Shell 测试全部通过;python3 tests/compose_database_config_test.py 通过,只渲染配置,不启动容器。未实际安装、升级或部署。

工作区默认忽略的 19 项全部另行显式执行通过:PostgreSQL 适配器 16 项、真实导入 1 项、测试辅助器 2 项。默认命令中的忽略不计作通过;工作区 feature、单包测试及过滤测试的范围不同且存在重叠,上表不累加成独立用例总数。此前的规则、完整正文单条/批量持久化和视频真实数据库回归结果保留在兼容性复核报告中。

中间轮次曾因旧测试辅助器留下的 IPC 残留导致 2 项网关测试和随后 10 项 WebSocket 测试初始化失败;没有把这些命令记为成功。现已修正三处辅助器的关闭路径,并只清理本轮确认创建、无连接且创建进程已退出的 11 个段,未清理此前已有的 21 个段,也未修改内核共享内存限制。

最终工作区、WebSocket、公开入口和身份隔离测试顺序运行前后的 IPC 清单一致,均为此前已有的 21 个段,无新增残留。单独用于数据库适配器及导入往返的临时 PostgreSQL 已正常停止并删除本次自有目录。

脚本范围:tests/deploy_state_safety_test.shtests/install_archive_safety_test.shtests/install_container_runtime_security_test.shtests/install_current_release_link_test.shtests/install_local_bundle_safety_test.shtests/install_privileged_write_safety_test.shtests/install_source_trust_test.shtests/release_supply_chain_test.shtests/tunnel_installer_config_security_test.shtests/update_compose_safety_test.sh

交付限制

本轮已确认、可复现且可在本仓库修复的剩余问题均已处理,未保留已确认却未修复的本轮源码问题;这一结论不等于“所有代码及所有部署环境绝无未知缺陷”。

这是本地源码、静态检查与隔离回归,不是对生产配置、第三方账户或所有部署组合的认证。上述验证未执行服务器部署或改动现有业务数据库;后续源码提交、推送不代表已经部署或完成生产环境验证。

已经被旧代码写空、删除、未采集的正文或视频字段不能由修复自动重建;仍在数据库中的旧内联/压缩正文可在修正后的保留链路中迁移。真实第三方 OAuth、支付、对象存储和远程隧道服务未使用生产凭据进行端到端验证。