Some checks failed
Lint / build (20) (push) Has been cancelled
- Remove hardcoded admin password, use env var or auto-generate - Fix trustHost to be conditional (Vercel-only by default) - Add HTTP security headers (CSP, X-Frame-Options, HSTS) - Create middleware.ts to activate existing rate limiting - Implement structured logging system - Rewrite error handling in ai-cad service - Update security documentation
237 lines
6.5 KiB
Markdown
237 lines
6.5 KiB
Markdown
# 安全改进总结
|
||
|
||
**日期**: 2026-05-05
|
||
**改进范围**: Phase 1 (安全短板) + Phase 2 (部分工程基础)
|
||
|
||
---
|
||
|
||
## 已完成的改进
|
||
|
||
### Phase 1: 安全短板修复 ✅
|
||
|
||
#### 1. 修复硬编码管理员密码 (create-admin.ts)
|
||
**风险等级**: 🟢 低风险
|
||
**改动**:
|
||
- 从环境变量 `ADMIN_EMAIL` / `ADMIN_PASSWORD` 读取凭据
|
||
- 如未设置则自动生成安全随机密码
|
||
- 不再将密码打印到 console(仅在自动生成时打印一次)
|
||
|
||
**向后兼容**: ✅ 是(未设置环境变量时使用默认邮箱 + 随机密码)
|
||
|
||
**测试建议**:
|
||
```bash
|
||
# 测试 1: 使用环境变量
|
||
ADMIN_EMAIL=admin@test.com ADMIN_PASSWORD=SecurePass123! node create-admin.ts
|
||
|
||
# 测试 2: 自动生成密码
|
||
node create-admin.ts
|
||
```
|
||
|
||
---
|
||
|
||
#### 2. 修复 trustHost 安全配置
|
||
**风险等级**: 🟡 中等风险
|
||
**改动**:
|
||
- `app/(auth)/auth.config.ts`: `trustHost` 改为条件启用
|
||
- Vercel 环境 (`VERCEL=1`) 自动开启
|
||
- 其他环境需显式设置 `AUTH_TRUST_HOST=true`
|
||
- `app/(auth)/auth.ts`: 移除重复的 `trustHost: true` 覆盖
|
||
|
||
**潜在影响**:
|
||
- ⚠️ 非 Vercel 部署且未设置 `AUTH_TRUST_HOST=true` 时,NextAuth 会严格校验 Host 头
|
||
- 如果反向代理未正确传递 Host 头,可能导致登录失败
|
||
|
||
**测试建议**:
|
||
```bash
|
||
# 开发环境测试登录流程
|
||
pnpm dev
|
||
# 访问 http://localhost:3000/login 测试登录
|
||
|
||
# 生产环境部署前检查
|
||
echo $VERCEL # Vercel 环境应为 "1"
|
||
echo $AUTH_TRUST_HOST # 非 Vercel 环境应设为 "true"
|
||
```
|
||
|
||
---
|
||
|
||
#### 3. 添加 HTTP 安全头
|
||
**风险等级**: 🟢 低风险
|
||
**改动**: `next.config.ts` 新增 `headers()` 函数
|
||
- `X-Content-Type-Options: nosniff`
|
||
- `X-Frame-Options: SAMEORIGIN`
|
||
- `Referrer-Policy: strict-origin-when-cross-origin`
|
||
- `Permissions-Policy: camera=(), microphone=(), geolocation=()`
|
||
- `Content-Security-Policy` (开发环境允许 unsafe-eval,生产环境更严格)
|
||
|
||
**潜在影响**:
|
||
- CSP 可能阻止某些第三方脚本(如未在 `connect-src` 白名单中的 API)
|
||
- 如有嵌入需求(iframe),需调整 `X-Frame-Options`
|
||
|
||
**测试建议**:
|
||
```bash
|
||
# 启动后检查响应头
|
||
curl -I http://localhost:3000 | grep -E "X-Content-Type|X-Frame|CSP"
|
||
```
|
||
|
||
---
|
||
|
||
#### 4. 创建 middleware.ts 接入 proxy.ts
|
||
**风险等级**: 🔴 **高风险** - 需重点测试
|
||
**改动**: 新建 `/middleware.ts`
|
||
```typescript
|
||
export { proxy as middleware, config } from "./proxy";
|
||
```
|
||
|
||
**影响**:
|
||
- ✅ 限流功能**首次生效**(之前 proxy.ts 存在但未被 Next.js 加载)
|
||
- ✅ IP 黑名单检查生效
|
||
- ✅ 可疑请求检测生效
|
||
- ⚠️ 所有 API 路由现在都会经过中间件检查
|
||
|
||
**潜在问题**:
|
||
1. **限流过严**: 如果用户正常使用触发限流(如画布自动保存频繁),会返回 429
|
||
2. **误判可疑请求**: `lib/security/request-monitor.ts` 的规则可能误报
|
||
3. **性能影响**: 每个请求都要经过 IP 检查、限流检查、可疑模式匹配
|
||
|
||
**测试建议**:
|
||
```bash
|
||
# 1. 检查中间件是否加载
|
||
pnpm build
|
||
cat .next/server/middleware-manifest.json # 应有内容,不再为空
|
||
|
||
# 2. 测试限流
|
||
# 快速刷新页面 100 次,应触发 429
|
||
|
||
# 3. 测试正常流程
|
||
# 登录、创建画布、上传图片、聊天 - 确保都正常工作
|
||
|
||
# 4. 检查日志
|
||
# 查看是否有 "[Security] Rate limit exceeded" 等日志
|
||
```
|
||
|
||
---
|
||
|
||
#### 5. 补充 .env.example
|
||
**风险等级**: 🟢 无风险(纯文档)
|
||
**新增条目**:
|
||
- `AUTH_URL` / `NEXTAUTH_URL`
|
||
- `AUTH_TRUST_HOST`
|
||
- `GOOGLE_CLIENT_ID` / `GOOGLE_CLIENT_SECRET`
|
||
- `ADMIN_EMAIL` / `ADMIN_PASSWORD`
|
||
- `FAL_KEY`
|
||
|
||
---
|
||
|
||
### Phase 2: 工程基础改进 ✅
|
||
|
||
#### 6. 建立结构化日志系统
|
||
**风险等级**: 🟢 低风险
|
||
**新增文件**: `lib/logger.ts`
|
||
- 提供 `log.info()`, `log.error()`, `log.warn()`, `log.debug()`
|
||
- 支持模块化日志:`createLogger("ModuleName")`
|
||
- 开发环境可读格式,生产环境 JSON 格式
|
||
- 通过 `LOG_LEVEL` 环境变量控制输出级别
|
||
|
||
**使用示例**:
|
||
```typescript
|
||
import { createLogger } from "@/lib/logger";
|
||
const log = createLogger("MyService");
|
||
log.error("Operation failed", error, { userId: "123" });
|
||
```
|
||
|
||
---
|
||
|
||
#### 7. 修复 service 层错误吞没
|
||
**风险等级**: 🟡 中等风险
|
||
**改动**:
|
||
- `services/ai-cad/index.ts`: 完全重写,所有 catch 块现在记录错误
|
||
- `services/canvas/index.ts`: 添加 logger 导入和辅助函数(未全部迁移)
|
||
|
||
**潜在问题**:
|
||
- `handleError(err, context, fallbackMessage)` 参数顺序与之前不同
|
||
- 如果有其他代码依赖 ai-cad service 的错误格式,可能受影响
|
||
|
||
**测试建议**:
|
||
```bash
|
||
# 触发一个 AI-CAD 错误(如无效的 workspace ID)
|
||
# 检查日志是否包含完整错误堆栈
|
||
```
|
||
|
||
---
|
||
|
||
#### 8. 更新安全文档
|
||
**风险等级**: 🟢 无风险(纯文档)
|
||
**改动**: `lib/security/IMPLEMENTATION_GUIDE.md` 更新至实际状态
|
||
|
||
---
|
||
|
||
## 未完成的任务
|
||
|
||
### Phase 2 剩余
|
||
- ❌ 为缺少验证的路由补充 Zod schema (enhance, rmbg, canvas/text-edit 等)
|
||
- ❌ 迁移剩余 service 文件的错误处理(canvas 有 31 个 catch 块未完全迁移)
|
||
|
||
### Phase 3
|
||
- ❌ 补充核心单元测试
|
||
- ❌ 添加 Dockerfile 支持
|
||
|
||
---
|
||
|
||
## 回滚方案
|
||
|
||
如果部署后出现问题,可以快速回滚:
|
||
|
||
### 回滚 middleware(最高优先级)
|
||
```bash
|
||
# 删除 middleware.ts,限流和安全检查将停止工作
|
||
rm middleware.ts
|
||
pnpm build
|
||
```
|
||
|
||
### 回滚 trustHost
|
||
```bash
|
||
# 在 auth.config.ts 中改回
|
||
trustHost: true,
|
||
```
|
||
|
||
### 回滚其他改动
|
||
```bash
|
||
git diff HEAD # 查看所有改动
|
||
git checkout HEAD -- <file> # 回滚单个文件
|
||
```
|
||
|
||
---
|
||
|
||
## 部署前检查清单
|
||
|
||
- [ ] 在开发环境运行 `pnpm dev`,确保无编译错误
|
||
- [ ] 测试登录/登出流程
|
||
- [ ] 测试聊天、画布、图片生成等核心功能
|
||
- [ ] 快速刷新页面,确认限流触发(应看到 429 错误)
|
||
- [ ] 检查 `.next/server/middleware-manifest.json` 不为空
|
||
- [ ] 设置生产环境变量:
|
||
- `AUTH_TRUST_HOST=true`(如非 Vercel)
|
||
- `LOG_LEVEL=warn`(生产环境)
|
||
- `ADMIN_PASSWORD=<secure-password>`(如需创建管理员)
|
||
- [ ] 运行 `pnpm build` 确保生产构建成功
|
||
|
||
---
|
||
|
||
## 监控建议
|
||
|
||
部署后前 24 小时重点监控:
|
||
|
||
1. **错误率**: 是否有大量 429 (限流) 或 403 (IP 黑名单) 错误
|
||
2. **登录成功率**: trustHost 改动可能影响登录
|
||
3. **日志输出**: 检查是否有 "[Security]" 前缀的警告
|
||
4. **性能**: 中间件增加的延迟(应 <10ms)
|
||
|
||
---
|
||
|
||
## 联系与支持
|
||
|
||
如遇问题,优先检查:
|
||
1. `.next/server/middleware-manifest.json` 是否正确生成
|
||
2. 浏览器控制台是否有 CSP 违规警告
|
||
3. 服务器日志中是否有 "[Security]" 相关错误
|