Skip to content

Latest commit

 

History

History
325 lines (244 loc) · 13.2 KB

File metadata and controls

325 lines (244 loc) · 13.2 KB

ERC Framework 最终审查报告

审查日期: 2026-05-11
审查工具: Cline AI Security Auditor
项目版本: v0.1.0


1. 安全修复回归验证

1.1 F-01 ~ F-09 修复状态

编号 问题 状态 证据 备注
F-01 SSRF白名单 ✅ Pass erc-gateway/src/types.rs 实现 validate_upstream_url(),检查 ALLOWED_UPSTREAM_HOSTS 白名单验证完整
F-02 限流竞态 ✅ Pass erc-gateway/src/main.rs 使用 SQLite UPSERT 原子操作 INSERT ... ON CONFLICT DO UPDATE ... RETURNING
F-03 Panic消除 ⚠️ Partial 仍有多处 unwrap() 存在 见技术债务清单
F-04 请求体大小限制 ✅ Pass erc-gateway/src/main.rs 设置 DefaultBodyLimit::max(10 * 1024 * 1024) 10MB 限制
F-05 上游响应验证 ✅ Pass erc-gateway/src/main.rs 实现响应体大小和 JSON 结构验证 50MB 限制
F-06 数据库文件权限 ✅ Pass erc-gateway/src/main.rs 调用 set_db_permissions() Windows/Unix 兼容
F-07 构建锁版本 ✅ Pass build.ps1 使用 --locked 标志 依赖版本锁定
F-08 Nonce原子递增 ✅ Pass erc-gateway/src/recorder.rs 使用 UPSERT 原子递增实现
F-09 bincode固定编码 ✅ Pass erc-core/src/receipt.rs 使用 with_fixint_encoding().with_little_endian() 固定编码配置

1.2 编译状态检查

状态: ❌ Fail

发现的编译错误:

  1. erc-core/src/receipt.rs:154 - tracing 模块未找到

    error[E0433]: cannot find module or crate `tracing` in this scope
    
  2. erc-core/src/lib.rs:63 - 类型不匹配

    error[E0308]: mismatched types
    expected `&[u8]`, found `&Result<Vec<u8>, String>`
    
  3. erc-core/src/lib.rs:73 - 返回类型错误

    error[E0308]: mismatched types
    expected `String`, found `Result<String, String>`
    

1.3 新增安全问题

问题 风险级别 位置 描述
硬编码 API Key 🔴 Critical .env UPSTREAM_API_KEY=sk-cbf75ae16aa94c90b2be554f27b4b87f 已提交到仓库
硬编码测试 Token 🟡 Medium public/trace-viewer.html token=test-token-123
unwrap/expect 调用 🟡 Medium 多处 见技术债务清单

2. 架构完整性

2.1 模块完整性评估

模块 状态 完整度 核心功能 备注
erc-core ⚠️ 编译错误 90% Receipt 结构体、Event 枚举、Ed25519 签名、Merkle 树 需修复编译错误
erc-gateway ✅ 完整 95% 透明代理、事件录制、限流、SSRF 防护 核心功能完整
erc-store ✅ 完整 100% SQLite 数据库封装、原子 Nonce、Event/Receipt 查询 功能完整
erc-query-api ✅ 完整 95% REST 端点、Token 认证、CORS 严格化 功能完整

2.2 核心功能验证

erc-gateway 透明代理

  • ✅ 请求转发到 UPSTREAM_URL
  • ✅ 支持多模型认证头格式(UPSTREAM_API_KEY / ANTHROPIC_API_KEY
  • ✅ 上游 URL 白名单验证
  • ✅ 请求体大小限制(10MB)
  • ✅ 响应体验证(50MB + JSON 结构检查)

erc-store 数据库封装

  • ✅ SQLite 连接管理
  • ✅ Event 流持久化(events 表)
  • ✅ Receipt 持久化(receipts 表)
  • ✅ 原子 Nonce 分配(nonce_counters 表)

erc-query-api 查询接口

  • GET /api/v1/receipts - Receipt 查询
  • GET /api/v1/traces/causality - 因果链查询
  • GET /api/v1/executions/events - 执行事件查询
  • ✅ API Token 认证(ERC_API_TOKEN
  • ✅ CORS 严格化(ERC_CORS_ORIGIN
  • ✅ Trace Viewer 静态页面

2.3 Trace Viewer 集成

  • public/trace-viewer.html 已存在
  • ✅ 通过 Query API 的静态文件服务提供访问
  • ⚠️ 硬编码测试 Token(test-token-123

3. 部署与配置一致性

3.1 Docker 配置检查

检查项 状态 备注
docker-compose.yml 与 Dockerfile 匹配 ✅ Pass 服务名和端口一致
Rust 基础镜像 ✅ Pass 使用 rust:1.82-slim
Cargo 国内源配置 ✅ Pass rsproxy.cn 镜像源
Python 依赖配置 ✅ Pass erc-sdk-py 已配置
健康检查配置 ✅ Pass 两个服务都有健康检查

3.2 环境变量覆盖

.env.example 覆盖情况:

变量 必填 默认值 状态
UPSTREAM_API_KEY ✅ 是 ✅ 已覆盖
ERC_API_TOKEN ✅ 是 ✅ 已覆盖
ALLOWED_UPSTREAM_HOSTS ✅ 是 ✅ 已覆盖
UPSTREAM_URL ❌ 否 https://api.deepseek.com/anthropic/v1/messages ✅ 已覆盖
ERC_CORS_ORIGIN ❌ 否 http://localhost:3000 ✅ 已覆盖
GATEWAY_LISTEN ❌ 否 0.0.0.0:8080 ✅ 已覆盖

3.3 QUICKSTART.md 与代码一致性

检查项 状态 备注
端口配置(8080/8082) ✅ 一致 代码和文档匹配
健康检查端点 ✅ 一致 /health 端点存在
API 端点路径 ✅ 一致 /api/v1/* 路径匹配
环境变量名称 ✅ 一致 变量名完全匹配

4. 文档与协议一致性

4.1 README.md 与代码一致性

检查项 状态 备注
架构图描述 ✅ 一致 四层架构(Gateway → Store → Query API → 审计)
核心特性描述 ✅ 一致 一行代码接入、不可篡改审计轨迹、独立可验证
快速开始步骤 ✅ 一致 Docker 部署流程正确
端口配置 ✅ 一致 8080 (Gateway) / 8082 (Query API)

4.2 FEATURE_VERIFICATION.md 准确性

功能项 标注状态 实际状态 一致性
Receipt 生成与签名 ✅ 一致
Event 录制 ✅ 一致
透明代理 ✅ 一致
认证授权 ✅ 一致
限流保护 ✅ 一致
CORS 配置 ✅ 一致
SSRF 防护 ✅ 一致
Panic 安全 ⚠️ ⚠️ ✅ 一致(标注准确)

4.3 FIX_REVIEW.md 修复项验证

所有 9 个修复项(F-01 ~ F-09)在代码中均有对应实现,文档与代码一致。

4.4 协议文档一致性

docs/SCHEMA.md (ERR/1.0)

  • ✅ 冻结声明存在
  • ✅ 不可变规则明确(禁止删除字段、禁止修改语义、新增字段必须放入 extensions)
  • ✅ 版本策略清晰
  • ✅ 引用 schemas/err-v1.schema.json 进行校验

docs/EVENTS.md (IEM/1.0)

  • ✅ 冻结声明存在
  • ✅ 6 种事件类型定义完整:
    • execution.started
    • execution.completed
    • llm.call.completed
    • tool.call.completed
    • policy.denied
    • approval.granted
  • ✅ 必填字段规范明确

代码实现与协议一致性

  • erc-core/src/receipt.rsExecutionReceipt 结构体包含所有冻结字段
  • erc-core/src/event.rsExecutionEvent 枚举包含所有 6 种事件类型
  • to_canonical_bytes() 使用 bincode 固定编码,符合协议要求

5. 技术债务清单

5.1 unwrap()/expect() 调用(按风险级别排序)

🔴 High Risk(网络绑定/服务器启动路径)

文件 行号 调用 风险
erc-query-api/src/main.rs 69 TcpListener::bind().await.unwrap() 服务器启动失败时 panic
erc-query-api/src/main.rs 70 axum::serve().await.unwrap() 服务器运行时 panic
erc-gateway/src/main.rs 67 TcpListener::bind().await.unwrap() 服务器启动失败时 panic
erc-gateway/src/main.rs 68 axum::serve().await.unwrap() 服务器运行时 panic

🟡 Medium Risk(数据库/配置路径)

文件 行号 调用 风险
erc-gateway/src/main.rs 37 .expect("无法打开限流数据库") 数据库打开失败时 panic
erc-gateway/src/main.rs 44 .expect("无法创建限流表") 表创建失败时 panic
erc-gateway/src/recorder.rs 20 .expect("无法打开SQLite数据库") 数据库打开失败时 panic
erc-gateway/src/recorder.rs 38 .expect("无法创建数据库表") 表创建失败时 panic
erc-store/src/lib.rs 17 Mutex::lock().unwrap_or_else() 锁获取失败时 exit
erc-query-api/src/main.rs 55 .parse().unwrap() CORS 解析失败时 panic

🟢 Low Risk(序列化路径)

文件 行号 调用 风险
erc-core/src/receipt.rs 141 serde_json::to_string().unwrap() JSON 序列化理论上不会失败
erc-core/src/receipt.rs 145 bincode::serialize().expect() bincode 序列化理论上不会失败

5.2 硬编码配置值

类型 位置 风险级别 建议
API Key .env sk-cbf75ae16aa94c90b2be554f27b4b87f 🔴 Critical 立即移除,使用环境变量注入
测试 Token public/trace-viewer.html test-token-123 🟡 Medium 移除或使用配置参数
默认监听地址 erc-gateway/src/types.rs 0.0.0.0:8080 🟢 Low 已通过环境变量覆盖
默认 CORS 源 erc-query-api/src/main.rs http://localhost:3000 🟢 Low 已通过环境变量覆盖

5.3 缺失的模块或功能

功能 状态 备注
多 Agent 因果图 ❌ 未实现 GET /api/v1/traces/causality 端点存在但功能有限
Stripe 计费集成 ❌ 未实现 需要后续开发
TEE 集成 ❌ 未实现 规划中
审计报告导出 ❌ 未实现 README 中标注"规划中"
LangChain Adapter ❌ 未实现 README 中标注"规划中"
Token 过期/刷新机制 ❌ 未实现 当前 Token 永不过期
并发限流测试 ❌ 缺失 建议编写 100 并发测试用例
cargo audit CI 集成 ❌ 缺失 建议集成到 CI/CD

5.4 代码冗余和最佳实践问题

问题 位置 描述 建议
编译错误 erc-core/src/receipt.rs tracing 模块未在 Cargo.toml 中声明依赖 添加 tracing = "0.1" 到 erc-core/Cargo.toml
类型不匹配 erc-core/src/lib.rs sign_and_clear() 调用参数类型错误 使用 ? 操作符处理 Result
重复的数据库连接逻辑 erc-gateway/src/main.rs / recorder.rs 两处都打开 SQLite 数据库 统一数据库连接管理
缺少错误处理 多处 网络错误直接 panic 使用 map_err() + 优雅降级

6. 总体结论与建议

6.1 项目评估

当前状态: ⚠️ 不具备对外交付条件

原因:

  1. 编译错误: erc-core 模块存在 3 个编译错误,无法正常构建
  2. 安全问题: .env 文件中包含硬编码的 API Key,已提交到仓库
  3. Panic 风险: 仍有多处 unwrap()/expect() 调用,在生产环境可能导致服务崩溃

6.2 优先修复建议

P0 - 阻塞性问题(必须立即修复)

  1. 修复编译错误

    • erc-core/Cargo.toml 添加 tracing = "0.1" 依赖
    • 修复 erc-core/src/lib.rs 中的类型不匹配问题
    • 确保 cargo build --release --locked 成功
  2. 移除硬编码敏感信息

    • .env 文件中移除真实的 API Key
    • .env 添加到 .gitignore(如果尚未添加)
    • 使用 .env.example 作为模板

P1 - 高优先级(发布前必须修复)

  1. 消除关键路径的 unwrap()

    • erc-query-api/src/main.rs:69-70 - TcpListener 绑定和服务器启动
    • erc-gateway/src/main.rs:67-68 - TcpListener 绑定和服务器启动
    • 使用 map_err() + process::exit(1) 或返回 Result
  2. 移除测试用硬编码值

    • public/trace-viewer.html 中的 test-token-123

P2 - 中优先级(建议在下一个版本修复)

  1. 消除剩余的 unwrap()/expect()

    • 数据库相关路径的错误处理
    • CORS 解析路径的错误处理
  2. 完善测试覆盖

    • 编写并发限流测试
    • 添加集成测试
  3. CI/CD 集成

    • 添加 cargo audit 到构建流程
    • 添加自动化测试

6.3 交付就绪检查清单

检查项 状态 阻塞级别
代码可编译 P0
无硬编码敏感信息 P0
关键路径无 panic P1
所有文档与代码一致 -
Docker 部署配置正确 -
环境变量覆盖完整 -
协议冻结声明完整 -
安全修复无回退 -

6.4 总结

ERC Framework 在架构设计和核心功能实现方面表现良好,文档与代码一致性高,安全修复措施基本到位。然而,由于存在编译错误和硬编码敏感信息,当前版本不具备对外交付条件

建议优先修复 P0 级别的问题(编译错误和敏感信息泄露),然后处理 P1 级别的 panic 风险。完成这些修复后,项目可以达到可交付状态。


审查完成时间: 2026-05-11 22:55 (Asia/Singapore)
审查范围: 全部 Rust 源代码、配置文件、文档、构建脚本、前端资源
审查方法: 静态代码分析、文档一致性检查、安全模式匹配