# Cyrene 第5轮调试报告:安全审计 + 边界条件 + 错误处理
> **日期**:2026-05-20 14:39 CST (UTC+8)
> **轮次**:第5轮
> **测试方法**:黑盒渗透测试 (curl + 手动审计)
> **测试范围**:Gateway (8080) 全端点
---
## 一、测试概况
| 类别 | 测试项数 | 通过 | 发现问题 |
|------|---------|------|---------|
| 认证绕过 | 9 | 8 | 1 |
| SQL注入 | 6 | 4 | 2 |
| XSS | 5 | 0 | 5 |
| 路径遍历 | 3 | 3 | 0 |
| 权限提升 | 1 | 1 | 0 |
| 速率限制 | 2 | 0 | 2 |
| 边界条件 | 10 | 5 | 5 |
| 错误处理 | 8 | 3 | 5 |
| **合计** | **44** | **24** | **20** |
---
## 二、严重发现 (🔴 Critical)
### 🔴 SEC-001: 注册/登录端点无速率限制
**位置**: [`backend/gateway/internal/router/router.go`](backend/gateway/internal/router/router.go:56-60)
**描述**: 登录 (`/auth/login`) 和注册 (`/auth/register`) 端点属于公开路由组,未应用限流中间件。`RateLimiter` 仅附加在 `protected` 路由组上。
**测试方法**:
```bash
for i in $(seq 1 20); do
curl -s -X POST http://localhost:8080/api/v1/auth/login \
-H 'Content-Type: application/json' \
-d '{"username":"admin","password":"wrong"}'
done
```
**实际结果**: 20次请求全部返回 `401`,无任何 `429 Too Many Requests`。
**预期结果**: 应在短时间内(如1秒内超过5次)返回 `429` 限流响应。
**影响**: 攻击者可对登录端点进行暴力破解,无限尝试密码组合。理论上 JWT 过期时间为 720 小时(30天),但暴力破解风险依然存在。
**严重级别**: 🔴 Critical
---
### 🔴 SEC-002: 用户名未做危险字符过滤 (Stored XSS + Log注入)
**位置**: [`backend/gateway/internal/handler/auth_handler.go`](backend/gateway/internal/handler/auth_handler.go:38-45)
**描述**: 注册端点接受包含 SQL 注入 payload、XSS payload 的用户名。虽然数据库查询使用了参数化查询(`$1`)防止了实际注入执行,但恶意字符串被原样存储到数据库,并嵌入到 JWT token 的 `user_id` 字段中。
**测试方法**:
```bash
curl -s -X POST http://localhost:8080/api/v1/auth/register \
-H 'Content-Type: application/json' \
-d '{"username":"test'\''; DROP TABLE users; --","password":"Test@123456",
"email":"sqli@test.com","nickname":"SQLiTest","verify_code":"000000"}'
```
**实际结果**: 用户成功注册,`user_id` 为 `user_test'; DROP TABLE users; --`,JWT token 中包含此 payload。用户可以使用此用户名正常登录。
**影响**:
1. 日志注入:用户名出现在日志中可能破坏日志格式
2. 存储型 XSS:如果前端任何地方直接渲染 `user_id` 而未转义
3. 数据完整性:数据库中存储了恶意构造的用户名
4. Token 膨胀:JWT 中包含特殊字符
**严重级别**: 🔴 Critical
---
### 🔴 SEC-003: 存储型 XSS — 所有内容端点未对输入做 HTML 转义
**位置**:
- [`backend/gateway/internal/handler/memory_handler.go`](backend/gateway/internal/handler/memory_handler.go)
- [`backend/gateway/internal/handler/knowledge_handler.go`](backend/gateway/internal/handler/knowledge_handler.go)
- [`backend/gateway/internal/handler/reminder_handler.go`](backend/gateway/internal/handler/reminder_handler.go)
**描述**: 记忆、知识库、提醒的标题/内容/便签字段接受并存储 HTML/JavaScript 代码。虽然 JSON 响应中使用了 Unicode 转义(如 `\u003cscript\u003e`),但这依赖 JSON 序列化器的默认行为,后端没有主动做输入验证或输出净化。
**测试方法**:
```bash
# 记忆
curl -X POST /api/v1/memory -H "Authorization: Bearer $TOKEN" \
-d '{"content":"
","category":"xss_test"}'
# 知识库
curl -X POST /api/v1/knowledge/bases -H "Authorization: Bearer $TOKEN" \
-d '{"name":"","description":"XSS test"}'
# 提醒
curl -X POST /api/v1/reminders -H "Authorization: Bearer $TOKEN" \
-d '{"title":"Test","note":"",...}'
```
**实际结果**: 所有 XSS payload 被原样存储到数据库。JSON 响应中由 Go 的 `encoding/json` 自动转义为 Unicode 形式。
**影响**: 如果前端渲染这些内容时使用 `dangerouslySetInnerHTML` 或未做 HTML 转义,将导致存储型 XSS 攻击。即使后端 JSON 有转义,前端可能自行解析。
**严重级别**: 🔴 Critical (取决于前端实现)
---
### 🔴 SEC-004: 文件名 XSS 过滤过于粗暴且不透明
**位置**: [`backend/gateway/internal/handler/file_handler.go`](backend/gateway/internal/handler/file_handler.go)
**描述**: 文件上传端点对文件名中的 `.txt"
```
**实际结果**: 文件名被变成 `script_.txt`(`<`, `/`, `>` 字符被移除)。原始文件名信息丢失。没有向用户说明文件名被修改的原因。
**影响**:
1. 用户提交 `filename=