102 lines
2.2 KiB
Plaintext
102 lines
2.2 KiB
Plaintext
---
|
||
description: 安全审查员规范 - 检查安全漏洞
|
||
alwaysApply: false
|
||
---
|
||
|
||
# 安全审查员规范
|
||
|
||
## 一、输入验证
|
||
|
||
### 检查项
|
||
- [ ] 所有用户输入是否经过 Zod 验证?
|
||
- [ ] 文件上传是否检查类型和大小限制?
|
||
- [ ] 是否防止了路径遍历攻击?
|
||
|
||
### 文件上传安全
|
||
```typescript
|
||
const MAX_TOTAL_SIZE = 500 * 1024 * 1024 // 500MB
|
||
const MAX_FILE_COUNT = 100
|
||
const MAX_SINGLE_FILE_SIZE = 200 * 1024 * 1024 // 200MB
|
||
|
||
// 解压前必须检查
|
||
let totalSize = 0
|
||
let fileCount = 0
|
||
for (const [name, file] of Object.entries(zip.files)) {
|
||
if (!file.dir) {
|
||
fileCount++
|
||
if (fileCount > MAX_FILE_COUNT) throw new Error('文件数量超限')
|
||
if (size > MAX_SINGLE_FILE_SIZE) throw new Error('单文件过大')
|
||
totalSize += size
|
||
}
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## 二、权限检查
|
||
|
||
### 检查项
|
||
- [ ] API 是否验证用户身份?
|
||
- [ ] 是否检查用户对资源的操作权限?
|
||
- [ ] 敏感操作是否有二次确认?
|
||
|
||
### 示例
|
||
```typescript
|
||
// 检查用户是否有权操作该资源
|
||
this.checkPermission(entity, ctx.user)
|
||
|
||
// 如果没有权限
|
||
throw new AppError(ErrorCode.AUTH_PERMISSION_DENIED)
|
||
```
|
||
|
||
---
|
||
|
||
## 三、常见漏洞
|
||
|
||
### SQL 注入
|
||
- **检查**:是否使用 Prisma 参数化查询
|
||
- **禁止**:字符串拼接 SQL
|
||
|
||
### XSS
|
||
- **检查**:React 自动转义 + DOMPurify 清理 HTML
|
||
- **禁止**:使用 `dangerouslySetInnerHTML` 未经清理
|
||
|
||
### CSRF
|
||
- **检查**:Next.js CSRF Token 保护
|
||
- **禁止**:跨域请求不带凭证
|
||
|
||
---
|
||
|
||
## 四、安全检查清单
|
||
|
||
| 检查项 | 说明 |
|
||
|--------|------|
|
||
| 身份验证 | API 是否验证 JWT/Session |
|
||
| 资源权限 | 用户是否有权操作该资源 |
|
||
| 输入验证 | 所有输入是否经过 Zod 验证 |
|
||
| 文件上传 | 是否检查类型、大小、路径 |
|
||
| SQL 注入 | 是否使用参数化查询 |
|
||
| XSS | 是否转义用户输入 |
|
||
| CSRF | 是否有 Token 保护 |
|
||
|
||
---
|
||
|
||
## 五、审查报告格式
|
||
|
||
```
|
||
## 安全审查结果
|
||
|
||
### 通过项 ✅
|
||
- 使用了 Zod 验证输入
|
||
- 使用了 Prisma 参数化查询
|
||
|
||
### 风险项 ⚠️
|
||
- 文件上传未检查路径遍历(第 X 行)
|
||
→ 修复:添加路径检查,禁止 .. 和绝对路径
|
||
|
||
### 严重漏洞 ❌
|
||
- 无
|
||
|
||
### 评分:X/10
|
||
```
|