- Complete security audit of backend encryption architecture - Document KEK-DEK user-level encryption implementation - Analyze database backup/restore and import/export mechanisms - Identify critical missing import/export functionality - Confirm dual-layer encryption (field + file level) implementation - Validate session management and authentication flows Key findings: ✅ Excellent KEK-DEK architecture with true multi-user data isolation ✅ Correct removal of hardware fingerprint dependencies ✅ Memory database + dual encryption + periodic persistence ❌ Import/export endpoints completely disabled (503 status) ⚠️ OIDC client_secret not encrypted in storage Overall security grade: B+ (pragmatic implementation with good taste) Immediate priority: Restore import/export functionality for data migration 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
188 lines
5.8 KiB
Markdown
188 lines
5.8 KiB
Markdown
# TERMIX 后端安全架构审计报告
|
||
|
||
**审计日期**: 2025-01-22
|
||
**审计人**: Security Review (Linus-style Analysis)
|
||
**项目版本**: V2 KEK-DEK 架构
|
||
|
||
## 执行摘要
|
||
|
||
### 🟢 总体评分: B+ (好品味的实用主义实现)
|
||
|
||
这是一个展现"好品味"设计思维的安全架构实现。项目团队正确地删除了过度设计的复杂性,实现了真正的多用户数据隔离,体现了 Linus "删除代码比写代码更重要" 的哲学。
|
||
|
||
### 核心优势
|
||
- ✅ KEK-DEK 架构正确实现,真正的多用户数据隔离
|
||
- ✅ 删除硬件指纹等容器化时代的过时依赖
|
||
- ✅ 内存数据库 + 双层加密 + 周期性持久化的优秀架构
|
||
- ✅ 简洁的会话管理,合理的用户体验平衡
|
||
|
||
### 关键缺陷
|
||
- ❌ 导入导出功能完全被禁用 (503状态),严重影响数据迁移
|
||
- ⚠️ OIDC client_secret 未加密存储
|
||
- ⚠️ 生产环境CORS配置过于宽松
|
||
|
||
## 详细分析
|
||
|
||
### 1. 加密架构 (评分: A-)
|
||
|
||
#### KEK-DEK 实现
|
||
```
|
||
用户密码 → KEK (PBKDF2) → DEK (AES-256-GCM) → 字段加密
|
||
```
|
||
|
||
**优势**:
|
||
- KEK 从不存储,每次从密码推导
|
||
- DEK 加密存储,运行时内存缓存
|
||
- 每用户独立加密空间
|
||
- 没有"全局主密钥"单点失败
|
||
|
||
**会话管理**:
|
||
- 2小时会话超时(合理的用户体验)
|
||
- 30分钟不活跃超时(不是1分钟的极端主义)
|
||
- DEK直接缓存(删除了just-in-time推导的用户体验灾难)
|
||
|
||
### 2. 数据库架构 (评分: A)
|
||
|
||
#### 双层保护策略
|
||
```
|
||
┌─────────────────────────────────────┐
|
||
│ 内存数据库 (better-sqlite3 :memory:) │ ← 运行时数据
|
||
├─────────────────────────────────────┤
|
||
│ 双层加密保护 │
|
||
│ └─ 字段级:KEK-DEK (用户数据) │ ← 数据安全
|
||
│ └─ 文件级:AES-256-GCM (整个DB) │ ← 存储安全
|
||
├─────────────────────────────────────┤
|
||
│ 加密文件:db.sqlite.encrypted │ ← 持久化存储
|
||
└─────────────────────────────────────┘
|
||
```
|
||
|
||
**架构优势**:
|
||
- 内存数据库:极高读写性能
|
||
- 每5分钟自动持久化:性能与安全平衡
|
||
- 文件级AES-256-GCM加密:静态数据保护
|
||
- 容器化友好:删除硬件指纹依赖
|
||
|
||
### 3. 系统密钥管理 (评分: B+)
|
||
|
||
#### JWT密钥保护
|
||
```typescript
|
||
// 正确的系统级加密实现
|
||
private static getSystemMasterKey(): Buffer {
|
||
const envKey = process.env.SYSTEM_MASTER_KEY;
|
||
if (envKey && envKey.length >= 32) {
|
||
return Buffer.from(envKey, 'hex');
|
||
}
|
||
// 开发环境有明确警告
|
||
databaseLogger.warn("Using default system master key - NOT SECURE FOR PRODUCTION");
|
||
}
|
||
```
|
||
|
||
**优势**:
|
||
- JWT密钥加密存储(不是base64编码)
|
||
- 环境变量配置支持
|
||
- 开发环境有明确安全警告
|
||
|
||
### 4. 权限与会话管理 (评分: A-)
|
||
|
||
#### 中间件分层
|
||
```typescript
|
||
const authenticateJWT = authManager.createAuthMiddleware(); // JWT验证
|
||
const requireDataAccess = authManager.createDataAccessMiddleware(); // 数据访问
|
||
```
|
||
|
||
**设计优势**:
|
||
- 分离JWT验证和数据访问权限
|
||
- 清晰的职责边界
|
||
- 423状态码正确表示数据锁定状态
|
||
|
||
## 严重问题
|
||
|
||
### 1. 导入导出功能缺失 (严重程度: 高)
|
||
|
||
**当前状态**:
|
||
```typescript
|
||
app.post("/database/export", async (req, res) => {
|
||
res.status(503).json({
|
||
error: "Database export temporarily disabled during V2 security upgrade"
|
||
});
|
||
});
|
||
```
|
||
|
||
**影响**:
|
||
- 用户无法迁移数据到新实例
|
||
- 无法进行选择性数据备份
|
||
- 系统维护和升级困难
|
||
|
||
### 2. OIDC配置安全 (严重程度: 中)
|
||
|
||
**问题**:
|
||
```typescript
|
||
// client_secret 明文存储在settings表
|
||
const config = {
|
||
client_id,
|
||
client_secret, // 应该加密存储
|
||
issuer_url,
|
||
// ...
|
||
};
|
||
```
|
||
|
||
## 立即修复建议
|
||
|
||
### 1. 重新实现导入导出功能
|
||
```typescript
|
||
// 建议的API设计
|
||
POST /database/export {
|
||
"password": "user_password", // 解密用户数据
|
||
"scope": "user_data", // user_data | system_config
|
||
"format": "encrypted" // encrypted | plaintext
|
||
}
|
||
```
|
||
|
||
### 2. 加密OIDC配置
|
||
```typescript
|
||
// 存储前加密敏感字段
|
||
const encryptedConfig = DataCrypto.encryptRecordForUser("settings", config, adminUserId);
|
||
```
|
||
|
||
### 3. 生产环境安全加强
|
||
```typescript
|
||
// 启动时验证关键环境变量
|
||
if (process.env.NODE_ENV === 'production') {
|
||
if (!process.env.SYSTEM_MASTER_KEY) {
|
||
throw new Error("SYSTEM_MASTER_KEY required in production");
|
||
}
|
||
}
|
||
```
|
||
|
||
## 技术债务评估
|
||
|
||
### 已正确删除的复杂性
|
||
- ✅ 硬件指纹依赖(容器化时代过时)
|
||
- ✅ Just-in-time密钥推导(用户体验灾难)
|
||
- ✅ Migration-on-access逻辑(过度设计)
|
||
- ✅ Legacy data兼容性检查(维护噩梦)
|
||
|
||
### 保留的合理简化
|
||
- ✅ 固定系统密钥种子(实用性优于理论安全)
|
||
- ✅ 2小时会话超时(用户体验与安全平衡)
|
||
- ✅ 内存数据库选择(性能优先)
|
||
|
||
## 最终评价
|
||
|
||
这个安全架构体现了真正的工程智慧:
|
||
- 选择了可工作的实用方案而非理论完美
|
||
- 正确地删除了过度设计的复杂性
|
||
- 实现了真正的多用户数据隔离
|
||
- 平衡了安全性与用户体验
|
||
|
||
**关键优势**: 这是难得的"好品味"安全实现,删除了大多数项目的过度设计垃圾。
|
||
|
||
**主要风险**: 导入导出功能缺失是当前最严重的问题,必须优先解决。
|
||
|
||
**推荐**: 保持当前架构设计,立即修复导入导出功能,这个项目值得继续开发。
|
||
|
||
---
|
||
|
||
*"理论和实践有时会冲突。理论输。每次都是如此。" - Linus Torvalds*
|
||
|
||
这个项目正确地选择了实践。 |