11 KiB
11 KiB
Security 审核报告
项目:AI-Ops 智能运维系统 审核日期:2026-05-11 审核范围:HLD.md(第 8 节、第 10.1 节)、INTERFACE.md、PRD.md、000001_init_schema.up.sql、TEST_DESIGN.md 审核人:Security Role
总体评级:B
安全设计具备基本框架,RBAC、审计日志、威胁建模等核心模块已有原则性设计,但存在多项与 fail-closed 策略冲突的设计缺陷、权限边界模糊、以及缺乏可落地的实现细则。在进入开发前必须修复 P0/P1 项,否则生产环境存在越权操作、审计失效和自愈引擎被滥用的风险。
优点
- 威胁建模已覆盖运维核心场景(自愈误触发、告警洪泛、越权操作、审计失真、外部适配层滥用),并映射到具体控制措施与验证要求(HLD 10.1)。
- 数据库层通过 BEFORE UPDATE/DELETE 触发器实现审计表 append-only,配合 CHECK 约束限制 action/risk_level 枚举值,基础防篡改机制存在(migration SQL)。
- RBAC 三角色权限矩阵在控制台层面有明确区分(viewer/operator/admin),并在响应头设计
X-Permitted-Actions返回(HLD 8.1)。 - 自愈引擎引入沙盘模式(dry-run)和级联故障自动回退设计,降低了自动化动作对生产环境的直接冲击(HLD 3.3)。
- 数据隔离在架构层面要求 tenant_id 过滤,并保留 Row Level Security(RLS)作为最后一道防线(HLD 8.3)。
- 测试设计将安全项纳入 CI 门禁:权限越界、审计篡改、SQL 注入均有测试用例(TEST_DESIGN.md 第 10 节)。
发现问题(按严重度 P0/P1/P2 分类)
P0 — 阻塞性风险(进入开发前必须修复)
| 编号 | 问题 | 证据 | 风险 |
|---|---|---|---|
| P0-001 | 审计写入失败时未阻断业务,与 fail-closed 策略直接冲突 | PRD F-5 明确写道:"审计日志存储满盘/写入失败 - 丢弃非关键字段或改为异步上报,不阻断业务操作"。HLD 10.2 和 TEST_DESIGN 8.1 虽声明"高风险操作审计失败即拒绝",但 PRD 的故障路径与之矛盾。 | 审计链路在降级场景下失效,无法保证"先写审计再执行业务",导致合规断裂和事后无法追责。 |
| P0-002 | 自愈引擎 invoke_script 缺少执行环境沙盘隔离 | HLD 3.3 定义 invoke_script 动作可"执行用户配置的程序化脚本",但文档中仅存在 dry-run 沙盘(验证动作逻辑),无任何关于脚本运行时隔离(容器化、seccomp、资源限制、网络策略、文件系统隔离)的设计。 | 攻击者或误配置可导致任意代码执行(RCE),直接控制生产环境或窃取密钥。 |
| P0-003 | 高风险变更二次确认可被 API 直接绕过 | HLD 3.5 和 10.1 将二次确认描述为"弹出二次确认窗口"(UI 层面),但未在 INTERFACE.md 或 HLD 中设计 API 层的防绕过机制(如二次确认令牌、幂等键、管理员数字签名)。 | 攻击者通过直接调用 REST API 即可绕过前端确认,执行影响面 >50% 的高风险变更。 |
P1 — 高风险(必须在上线前修复)
| 编号 | 问题 | 证据 | 风险 |
|---|---|---|---|
| P1-001 | 审计防篡改机制无法抵御特权用户攻击 | migration SQL 中的触发器可被超级用户(postgres)或具有 TRIGGER/ALTER 权限的用户禁用或删除;缺少对 DDL 操作(DROP TRIGGER、ALTER TABLE)的审计;无哈希链或数字签名。 | 拥有数据库高权限的内部人员或入侵者可静默抹除审计痕迹。 |
| P1-002 | 外部管理接口攻击面过大,API Key 管理缺失 | HLD 7.1 指出 AI-Ops 通过 POST /internal/gateway/switch-route、throttle、restart 等接口直接控制 gateway。独立运行时使用"API Key 鉴权",但未描述 Key 的存储、轮换、最小权限、生命周期管理。 | 若 AI-Ops 服务被攻破,攻击者可一键切流、限流或重启实例,造成生产事故。 |
| P1-003 | RBAC 缺少自愈动作与资源级权限控制 | HLD 8.1 RBAC 矩阵未包含"执行自愈动作"权限;INTERFACE.md 3.2 的 POST /api/v1/ai-ops/healing/execute 未标注角色要求;PRD AC-12 未限制 operator 是否可触发人工自愈。同时缺少同角色用户只能操作自己创建的资源的水平越权防护。 | operator 可能执行超出职责范围的自愈动作;用户 A 可修改/回滚用户 B 创建的规则。 |
| P1-004 | 敏感数据在配置表和审计日志中无加密存储设计 | ai_ops_channels.config 存储 Webhook URL 和密钥;ai_ops_rules.healing_config 可能包含管理 API 凭据;HLD 8.2 仅声明 Sanitizer 脱敏,无字段级加密或密钥托管设计。 | 数据库备份泄露、SQL 注入成功或内部人员越权查询即可直接获取明文密钥。 |
| P1-005 | SQL 注入与 PromQL 注入缺少架构级强制约束 | TEST_DESIGN.md 有 SQL 注入测试项,但 HLD/INTERFACE 中未强制要求所有 SQL 必须使用参数化查询。threshold_value 支持 regex 类型,若该值被拼接进 PromQL 或 SQL,存在注入风险。 | 攻击者通过构造恶意阈值规则,可能读取未授权数据或篡改时序查询。 |
P2 — 中等风险(建议修复)
| 编号 | 问题 | 证据 | 风险 |
|---|---|---|---|
| P2-001 | 威胁建模缺少 OWASP Top 10 系统性映射和 LLM/Gateway 特有风险 | HLD 10.1 的 5 个威胁场景覆盖运维故障较多,但未明确映射 A02、A05、A06、A07、A10。对于 LLM 网关场景,缺少对 Prompt Injection、Model DoS、SSRF 的专项分析。 | 安全测试覆盖不全,可能导致未知攻击面遗漏。 |
| P2-002 | 影响面计算单一,无法覆盖多种高风险场景 | HLD 3.5 仅通过"拒绝率 > 50%"判定高风险。未考虑告警阈值过度敏感导致的告警风暴、通知渠道误删导致的告警黑洞等。 | 真正的风险变更可能被误判为低风险,绕过二次确认。 |
| P2-003 | /metrics 和 WebSocket 接口的鉴权与限流设计缺失 | /metrics 对外暴露;WebSocket /ws/v1/ai-ops/alerts 未描述 JWT 验证、连接数限制、订阅权限校验。 | 潜在信息泄露和 DoS 攻击面。 |
| P2-004 | 错误码重复定义且 HTTP 状态码语义不一致 | INTERFACE.md 3.3 中 OPS_AUD_4101 出现两次,OPS_AUD_4001 定义为"无权进行审计操作"却对应 403。 | 客户端错误处理混乱,增加集成方开发成本。 |
| P2-005 | 审计日志外键允许隐式修改审计记录 | migration SQL 中 parent_audit_id 使用 ON DELETE SET NULL。虽触发器阻止 DELETE on ai_ops_audits,但如果 TRUNCATE 或超级用户绕过,子记录的 parent_audit_id 会被设为 NULL。 | 审计关联完整性受损,影响回滚追溯。 |
| P2-006 | 回滚操作自身缺少版本并发控制 | HLD 3.5 提到回滚前检查目标资源是否被后续修改覆盖(返回 4102),但未明确回滚执行期间是否加乐观锁或分布式锁。 | 并发回滚与修改可能导致配置状态进一步损坏。 |
改进建议
-
统一 fail-closed 策略,消除文档冲突
- 修改 PRD F-5:将"审计写入失败不阻断业务"改为"审计写入失败时,高风险操作必须拒绝执行;低风险操作可降级至本地队列缓存,但必须在 5 分钟内补写成功,否则触发 P1 内部告警"。
- 在 HLD 5.3 配置回滚流程和告警规则变更流程中,明确画出"先写审计表(INSERT ai_ops_audits) -> 获得 audit_id -> 执行业务 SQL -> 更新审计结果"的时序图。
-
为 invoke_script 增加运行时沙盘
- 采用 gVisor、Firecracker 或至少 Docker + seccomp + 只读根文件系统运行用户脚本。
- 限制:禁止访问环境变量 secrets、禁止出站网络(除白名单外)、CPU/内存硬限制、执行超时强制 kill。
- 脚本内容在保存前需经过静态安全扫描(如禁止 os.exec、net.Dial 等敏感调用)。
-
在 API 层实现不可绕过的二次确认机制
- 对影响面 > 50% 的变更,后端生成一次性 confirmation_token(绑定用户、资源、变更哈希、TTL=5min),前端弹窗只是展示层。
- 执行高风险 API 时必须在请求头中携带有效的 confirmation_token,否则返回需要二次确认。
- 该机制同时适用于回滚操作。
-
加固审计防篡改能力
- 引入审计日志哈希链:每条新记录包含 previous_hash = SHA256(上一条记录的 id + created_at + 内容),应用层计算并存储。
- 对 ai_ops_audits 启用 pgaudit 扩展,记录所有 DDL 和超级用户操作。
- 定期(每日)将审计日志摘要写入不可篡改的外部存储(如 WORM 存储或独立只读实例)。
- 将 parent_audit_id 的 ON DELETE SET NULL 改为 ON DELETE RESTRICT。
-
细化 RBAC 并增加资源级鉴权
- 扩展 RBAC 矩阵:增加 healing:execute、channel:manage、capacity:threshold_write 等细粒度权限。
- 增加资源所有者概念:用户只能修改/删除自己创建的 rules/channels,admin 可绕过此限制。
- 在独立运行模式下为 ai_ops_roles 增加权限位字段(bitmask),避免硬编码角色逻辑。
-
强制参数化查询与注入防护
- 在 HLD 技术约束中增加条款:所有 SQL 操作必须使用 pgx 参数化查询,禁止字符串拼接 SQL。所有 PromQL 操作必须经过白名单校验。
- threshold_type = 'regex' 的场景,regex 值只应用于应用层阈值评估,不应作为 SQL LIKE 或 PromQL 的查询条件。
-
加密存储敏感配置
- ai_ops_channels.config 和 ai_ops_rules.healing_config 中的敏感字段在写入前使用 AES-256-GCM 加密,密钥由外部 KMS/Vault 托管。
- 审计日志的 before_state / after_state 在序列化前由 Sanitizer 递归扫描并替换敏感值为 "REDACTED",确保 JSONB 中洼套的密钥均被脱敏。
-
缩小外部接口攻击面
- 为 /internal/gateway/* 接口引入短期有效的 mTLS 或至少 HMAC-SHA256 签名验证,API Key 存储在内存加密空间(非环境变量明文)。
- WebSocket 接口实现 JWT Token 验证和每 IP 最大连接数限制。
- /metrics 端点增加 IP 白名单或基础鉴权,避免暴露过多内部元数据。
门禁检查清单(进入开发前必须通过)
- PRD F-5 修正:审计写入失败时高风险操作必须拒绝(fail-closed)。
- HLD 补充二次确认 API 防绕过机制设计。
- HLD 补充 invoke_script 运行时沙盘隔离方案。
- RBAC 矩阵增加自愈执行、通知渠道、容量阈值等细粒度权限。
- 审计触发器增加 pgaudit DDL 监控 + 哈希链设计。
- 数据库层强制参数化查询约束落地到 HLD 技术约束中。
- 敏感配置字段加密存储方案确认。
- 错误码重复定义问题修复并与前端对齐。