# 安全性检查

本文档详细说明如何使用 AI 分析代码安全问题。

## 📋 概述

安全性检查是智能代码审查的关键维度，通过识别常见的安全漏洞和风险，帮助开发者提升代码安全性，防止潜在的安全攻击。

## 🎯 检查维度

### 1. SQL 注入（SQL Injection）

**风险等级**: 🔴 HIGH

**描述**: 攻击者通过恶意构造的输入篡改数据库查询逻辑。

**检测模式**:
- 字符串拼接 SQL 语句
- 直接使用用户输入构造查询
- 未使用参数化查询

**示例**:
```go
// ❌ 存在 SQL 注入风险
query := "SELECT * FROM users WHERE username = '" + username + "'"
db.Query(query)

// ✅ 安全的参数化查询
query := "SELECT * FROM users WHERE username = ?"
db.Query(query, username)
```

**修复建议**:
1. 使用参数化查询或 ORM
2. 对用户输入进行验证和转义
3. 使用最小权限的数据库账户

### 2. XSS 跨站脚本（Cross-Site Scripting）

**风险等级**: 🔴 HIGH

**描述**: 攻击者在网页中注入恶意脚本，窃取用户信息或进行攻击。

**检测模式**:
- 直接输出用户输入到 HTML
- 未对用户输入进行 HTML 转义
- 使用 `innerHTML` 直接插入用户内容

**示例**:
```javascript
// ❌ 存在 XSS 风险
div.innerHTML = userComment;
document.write(userName);

// ✅ 安全的 HTML 转义
div.textContent = userComment;
div.innerHTML = escapeHtml(userComment);

function escapeHtml(text) {
    return text
        .replace(/&/g, "&amp;")
        .replace(/</g, "&lt;")
        .replace(/>/g, "&gt;")
        .replace(/"/g, "&quot;")
        .replace(/'/g, "&#039;");
}
```

**修复建议**:
1. 对用户输入进行 HTML 转义
2. 使用 `textContent` 而非 `innerHTML`
3. 使用 CSP（Content Security Policy）
4. 对输出进行白名单验证

### 3. 敏感信息泄露（Sensitive Data Exposure）

**风险等级**: 🔴 HIGH

**描述**: 代码中包含硬编码的密钥、密码、Token 等敏感信息。

**检测模式**:
- 硬编码的密码、密钥、Token
- 代码中包含 API 密钥
- 敏感配置信息

**示例**:
```go
// ❌ 硬编码敏感信息
const (
    DB_PASSWORD = "admin123"
    API_KEY     = "sk-1234567890abcdef"
    SECRET_KEY  = "my-secret-key"
)

// ✅ 使用环境变量
dbPassword := os.Getenv("DB_PASSWORD")
apiKey := os.Getenv("API_KEY")
secretKey := os.Getenv("SECRET_KEY")
```

**修复建议**:
1. 使用环境变量存储敏感信息
2. 使用配置管理工具（如 Vault）
3. 不要在代码中硬编码密钥
4. 使用 `.env` 文件并加入 `.gitignore`

### 4. 认证和授权问题（Authentication & Authorization）

**风险等级**: 🔴 HIGH

**描述**: 认证或授权机制存在缺陷，导致未授权访问。

**检测模式**:
- 缺少认证检查
- 权限验证不充分
- 会话管理不当

**示例**:
```go
// ❌ 缺少权限检查
func getUserProfile(userID int) (*User, error) {
    return db.GetUser(userID)
}

// ✅ 添加权限检查
func getUserProfile(userID int, currentUser *User) (*User, error) {
    // 检查是否有权限访问该用户信息
    if currentUser.ID != userID && !currentUser.IsAdmin {
        return nil, ErrPermissionDenied
    }
    return db.GetUser(userID)
}
```

**修复建议**:
1. 每个敏感操作都要进行权限检查
2. 使用最小权限原则
3. 实施适当的会话管理
4. 定期轮换密钥和证书

### 5. 输入验证（Input Validation）

**风险等级**: ⚠️ MEDIUM

**描述**: 对用户输入缺少充分的验证，可能导致各种安全问题。

**检测模式**:
- 缺少输入长度检查
- 缺少输入格式验证
- 缺少类型检查

**示例**:
```javascript
// ❌ 缺少输入验证
function createUser(username, password) {
    db.insert({ username, password });
}

// ✅ 添加输入验证
function createUser(username, password) {
    if (!username || username.length < 3 || username.length > 20) {
        throw new Error('用户名长度必须在 3-20 个字符之间');
    }

    if (!/^[a-zA-Z0-9_]+$/.test(username)) {
        throw new Error('用户名只能包含字母、数字和下划线');
    }

    if (!password || password.length < 8) {
        throw new Error('密码长度至少为 8 个字符');
    }

    db.insert({ username, password });
}
```

**修复建议**:
1. 验证输入长度、格式、类型
2. 使用白名单而非黑名单
3. 在客户端和服务端都进行验证
4. 对不同来源的输入都要验证

### 6. 资源泄漏（Resource Leak）

**风险等级**: ⚠️ MEDIUM

**描述**: 资源（文件、连接、内存）未正确释放，可能导致 DoS。

**检测模式**:
- 文件打开后未关闭
- 数据库连接未关闭
- 网络连接未关闭

**示例**:
```go
// ❌ 资源未关闭
func processData(filename string) error {
    file, _ := os.Open(filename)
    // 处理文件
    // 忘记关闭文件

    db, _ := sql.Open("mysql", dsn)
    // 处理数据库
    // 忘记关闭连接
}

// ✅ 使用 defer 确保资源关闭
func processData(filename string) error {
    file, err := os.Open(filename)
    if err != nil {
        return err
    }
    defer file.Close()

    db, err := sql.Open("mysql", dsn)
    if err != nil {
        return err
    }
    defer db.Close()

    // 处理文件和数据库
    return nil
}
```

**修复建议**:
1. 使用 `defer` 确保资源释放
2. 使用 `try-with-resources`（Java）
3. 使用连接池管理数据库连接
4. 定期检查和清理资源

### 7. 不安全的随机数（Insecure Randomness）

**风险等级**: ⚠️ MEDIUM

**描述**: 使用可预测的随机数生成器，可能被攻击者预测。

**检测模式**:
- 使用 `Math.random()` 生成安全相关随机数
- 使用时间戳作为随机种子
- 使用线性同余生成器

**示例**:
```javascript
// ❌ 不安全的随机数
const token = Math.random().toString(36);
const seed = Date.now();
const random = srand(seed);

// ✅ 安全的随机数
const crypto = require('crypto');
const token = crypto.randomBytes(16).toString('hex');
```

**修复建议**:
1. 使用加密安全的随机数生成器
2. 不要使用时间戳作为随机种子
3. 对于密钥、Token 等安全相关数据，使用 CSPRNG

### 8. 不安全的反序列化（Insecure Deserialization）

**风险等级**: 🔴 HIGH

**描述**: 反序列化不受信任的数据可能导致远程代码执行。

**检测模式**:
- 反序列化用户输入
- 使用不安全的序列化格式
- 缺少完整性验证

**示例**:
```java
// ❌ 不安全的反序列化
Object obj = deserializeObject(userInput);

// ✅ 安全的反序列化
// 1. 使用白名单限制可反序列化的类型
// 2. 验证数据的完整性
// 3. 使用安全的序列化格式（如 JSON）
```

**修复建议**:
1. 避免反序列化不受信任的数据
2. 使用白名单限制可反序列化的类型
3. 使用安全的序列化格式（如 JSON）
4. 验证数据的完整性和来源

## 🔧 分析流程

```
开始安全性分析
  ↓
1. 解析代码结构
  ├─ 识别数据库操作
  ├─ 识别用户输入处理
  └─ 识别敏感信息
  ↓
2. 检测安全漏洞
  ├─ SQL 注入
  ├─ XSS 跨站脚本
  ├─ 敏感信息泄露
  ├─ 认证授权问题
  ├─ 输入验证
  ├─ 资源泄漏
  ├─ 不安全的随机数
  └─ 不安全的反序列化
  ↓
3. 评估风险等级
  ├─ 根据漏洞类型评估
  ├─ 根据上下文评估
  └─ 根据影响范围评估
  ↓
4. 生成安全报告
  ├─ 漏洞列表
  ├─ 风险等级
  └─ 修复建议
  ↓
完成
```

## 📊 输出格式

### JSON 格式

```json
{
  "security_analysis": {
    "overall_score": 70,
    "status": "NEEDS_REVIEW",
    "vulnerabilities": [
      {
        "id": 1,
        "severity": "HIGH",
        "category": "sql_injection",
        "title": "SQL 注入漏洞",
        "file": "src/auth/login.go",
        "line": 45,
        "code_snippet": "query := \"SELECT * FROM users WHERE username = '\" + username + \"'\"",
        "description": "直接拼接用户输入到 SQL 语句，存在 SQL 注入风险",
        "impact": "攻击者可以通过构造恶意输入访问或篡改数据库",
        "recommendation": "使用参数化查询或 ORM",
        "references": [
          "https://owasp.org/www-community/attacks/SQL_Injection",
          "https://cheatsheetseries.owasp.org/cheatsheets/SQL_Injection_Prevention_Cheat_Sheet.html"
        ]
      },
      {
        "id": 2,
        "severity": "HIGH",
        "category": "sensitive_data",
        "title": "敏感信息泄露",
        "file": "config/database.go",
        "line": 10,
        "code_snippet": "const DB_PASSWORD = \"admin123\"",
        "description": "代码中硬编码数据库密码",
        "impact": "敏感信息可能被泄露，导致数据库被攻击",
        "recommendation": "使用环境变量或配置管理工具存储敏感信息",
        "references": [
          "https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html"
        ]
      }
    ],
    "summary": {
      "total": 5,
      "critical": 0,
      "high": 2,
      "medium": 3,
      "low": 0
    }
  }
}
```

### Markdown 格式

```markdown
## 安全性分析: 70/100 ⚠️

### 🔴 高危漏洞（2）

#### 1. SQL 注入漏洞
- **文件**: `src/auth/login.go:45`
- **风险等级**: 🔴 HIGH
- **类别**: sql_injection
- **代码**:
  ```go
  query := "SELECT * FROM users WHERE username = '" + username + "'"
  ```
- **描述**: 直接拼接用户输入到 SQL 语句，存在 SQL 注入风险
- **影响**: 攻击者可以通过构造恶意输入访问或篡改数据库
- **修复建议**: 使用参数化查询或 ORM
- **参考**:
  - [OWASP SQL Injection](https://owasp.org/www-community/attacks/SQL_Injection)
  - [SQL Injection Prevention Cheat Sheet](https://cheatsheetseries.owasp.org/cheatsheets/SQL_Injection_Prevention_Cheat_Sheet.html)

#### 2. 敏感信息泄露
- **文件**: `config/database.go:10`
- **风险等级**: 🔴 HIGH
- **类别**: sensitive_data
- **代码**:
  ```go
  const DB_PASSWORD = "admin123"
  ```
- **描述**: 代码中硬编码数据库密码
- **影响**: 敏感信息可能被泄露，导致数据库被攻击
- **修复建议**: 使用环境变量或配置管理工具存储敏感信息

### ⚠️ 中危漏洞（3）

#### 1. 输入验证缺失
- **文件**: `src/api/user.go:78`
- **风险等级**: ⚠️ MEDIUM
- **修复建议**: 添加用户名和密码的格式验证

### 📊 漏洞统计

- 总计: 5 个漏洞
- 🔴 高危: 2 个
- ⚠️ 中危: 3 个
- ℹ️ 低危: 0 个

### 📝 安全建议

1. **立即修复**：修复所有高危漏洞，特别是 SQL 注入和敏感信息泄露
2. **加强验证**：对所有用户输入进行严格的格式和长度验证
3. **使用工具**：集成静态安全分析工具（如 SonarQube、Snyk）
4. **定期审计**：定期进行安全代码审查

### 📚 参考资源

- [OWASP Top 10](https://owasp.org/www-project-top-ten/)
- [OWASP Cheat Sheet Series](https://cheatsheetseries.owasp.org/)
- [CWE Top 25](https://cwe.mitre.org/top25/)
```

## 💡 最佳实践

### 1. 防御 SQL 注入

```go
// ✅ 使用参数化查询
stmt, err := db.Prepare("SELECT * FROM users WHERE username = ?")
if err != nil {
    return err
}
defer stmt.Close()

rows, err := stmt.Query(username)
if err != nil {
    return err
}
defer rows.Close()

// ✅ 使用 ORM
var user User
result := db.Where("username = ?", username).First(&user)
```

### 2. 防御 XSS 攻击

```javascript
// ✅ 使用 DOMPurify 库
import DOMPurify from 'dompurify';

const clean = DOMPurify.sanitize(userInput);
div.innerHTML = clean;

// ✅ 使用 CSP
// 在 HTML 头中添加 CSP
<meta http-equiv="Content-Security-Policy" content="default-src 'self'; script-src 'self'">
```

### 3. 保护敏感信息

```go
// ✅ 使用环境变量
dbPassword := os.Getenv("DB_PASSWORD")

// ✅ 使用配置文件（加密）
config := loadConfig("config.enc")

// ✅ 使用密钥管理服务
secret := vault.GetSecret("database_password")
```

## 🔍 常见问题

### Q: 如何确定漏洞的风险等级？

**A**: 综合考虑以下因素：
- **利用难度**: 容易利用的漏洞风险更高
- **影响范围**: 影响范围大的漏洞风险更高
- **数据敏感性**: 涉及敏感数据的漏洞风险更高
- **业务影响**: 对业务影响大的漏洞风险更高

### Q: 如何处理误报？

**A**:
1. 审查代码上下文，确认是否真的存在安全风险
2. 如果是误报，添加注释说明为什么是安全的
3. 可以配置白名单忽略特定规则
4. 提供反馈改进安全检查规则

### Q: 安全审查如何与 CI/CD 集成？

**A**:
1. 在 CI 流程中添加安全扫描步骤
2. 设置安全门禁（如不允许高危漏洞合并）
3. 定期生成安全报告
4. 集成 SAST 工具（如 SonarQube、Snyk）

## 📚 相关文档

- [OWASP Top 10](https://owasp.org/www-project-top-ten/) - Web 应用安全风险
- [代码质量检查](code-review-quality.md) - 代码质量分析
- [性能检查](code-review-performance.md) - 性能分析

---

*最后更新: 2026-06-12*
