Files
ai-ops/tech/SECURITY_AUDIT_REPORT.md
2026-05-12 17:48:22 +08:00

112 lines
11 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.
## 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 项,否则生产环境存在越权操作、审计失效和自愈引擎被滥用的风险。
---
### 优点
1. 威胁建模已覆盖运维核心场景自愈误触发、告警洪泛、越权操作、审计失真、外部适配层滥用并映射到具体控制措施与验证要求HLD 10.1)。
2. 数据库层通过 BEFORE UPDATE/DELETE 触发器实现审计表 append-only配合 CHECK 约束限制 action/risk_level 枚举值基础防篡改机制存在migration SQL
3. RBAC 三角色权限矩阵在控制台层面有明确区分viewer/operator/admin并在响应头设计 `X-Permitted-Actions` 返回HLD 8.1)。
4. 自愈引擎引入沙盘模式dry-run和级联故障自动回退设计降低了自动化动作对生产环境的直接冲击HLD 3.3)。
5. 数据隔离在架构层面要求 tenant_id 过滤,并保留 Row Level SecurityRLS作为最后一道防线HLD 8.3)。
6. 测试设计将安全项纳入 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但未明确回滚执行期间是否加乐观锁或分布式锁。 | 并发回滚与修改可能导致配置状态进一步损坏。 |
---
### 改进建议
1. **统一 fail-closed 策略,消除文档冲突**
- 修改 PRD F-5将"审计写入失败不阻断业务"改为"审计写入失败时,高风险操作必须拒绝执行;低风险操作可降级至本地队列缓存,但必须在 5 分钟内补写成功,否则触发 P1 内部告警"。
- 在 HLD 5.3 配置回滚流程和告警规则变更流程中,明确画出"先写审计表INSERT ai_ops_audits -> 获得 audit_id -> 执行业务 SQL -> 更新审计结果"的时序图。
2. **为 invoke_script 增加运行时沙盘**
- 采用 gVisor、Firecracker 或至少 Docker + seccomp + 只读根文件系统运行用户脚本。
- 限制:禁止访问环境变量 secrets、禁止出站网络除白名单外、CPU/内存硬限制、执行超时强制 kill。
- 脚本内容在保存前需经过静态安全扫描(如禁止 os.exec、net.Dial 等敏感调用)。
3. **在 API 层实现不可绕过的二次确认机制**
- 对影响面 > 50% 的变更,后端生成一次性 confirmation_token绑定用户、资源、变更哈希、TTL=5min前端弹窗只是展示层。
- 执行高风险 API 时必须在请求头中携带有效的 confirmation_token否则返回需要二次确认。
- 该机制同时适用于回滚操作。
4. **加固审计防篡改能力**
- 引入审计日志哈希链:每条新记录包含 previous_hash = SHA256(上一条记录的 id + created_at + 内容),应用层计算并存储。
- 对 ai_ops_audits 启用 pgaudit 扩展,记录所有 DDL 和超级用户操作。
- 定期(每日)将审计日志摘要写入不可篡改的外部存储(如 WORM 存储或独立只读实例)。
- 将 parent_audit_id 的 ON DELETE SET NULL 改为 ON DELETE RESTRICT。
5. **细化 RBAC 并增加资源级鉴权**
- 扩展 RBAC 矩阵:增加 healing:execute、channel:manage、capacity:threshold_write 等细粒度权限。
- 增加资源所有者概念:用户只能修改/删除自己创建的 rules/channelsadmin 可绕过此限制。
- 在独立运行模式下为 ai_ops_roles 增加权限位字段bitmask避免硬编码角色逻辑。
6. **强制参数化查询与注入防护**
- 在 HLD 技术约束中增加条款:所有 SQL 操作必须使用 pgx 参数化查询,禁止字符串拼接 SQL。所有 PromQL 操作必须经过白名单校验。
- threshold_type = 'regex' 的场景regex 值只应用于应用层阈值评估,不应作为 SQL LIKE 或 PromQL 的查询条件。
7. **加密存储敏感配置**
- ai_ops_channels.config 和 ai_ops_rules.healing_config 中的敏感字段在写入前使用 AES-256-GCM 加密,密钥由外部 KMS/Vault 托管。
- 审计日志的 before_state / after_state 在序列化前由 Sanitizer 递归扫描并替换敏感值为 "***REDACTED***",确保 JSONB 中洼套的密钥均被脱敏。
8. **缩小外部接口攻击面**
- 为 /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 技术约束中。
- [ ] 敏感配置字段加密存储方案确认。
- [ ] 错误码重复定义问题修复并与前端对齐。