# 安全编码

## 规则（Rules）

# 安全编码 - 规范

## SQL 注入防护
```javascript
// ❌ 错误：字符串拼接
const sql = `SELECT * FROM users WHERE name = '${name}'`;

// ✅ 正确：参数化查询
const sql = 'SELECT * FROM users WHERE name = ?';
db.query(sql, [name]);
```

## XSS 防护
```html
<!-- ❌ 错误：直接输出用户输入 -->
<div>{{ user_input }}</div>
<!-- ✅ 正确：HTML 转义输出 -->
<div>{{ escapeHtml(user_input) }}</div>
```

```javascript
// 安全 HTTP 头
res.setHeader('X-Content-Type-Options', 'nosniff');
res.setHeader('X-Frame-Options', 'DENY');
res.setHeader('X-XSS-Protection', '1; mode=block');
res.setHeader('Content-Security-Policy', "default-src 'self'");
```

## 敏感信息处理

| 数据类型 | 处理方式 |
|:---------|:---------|
| 密码 | bcrypt 哈希（成本因子 ≥ 10） |
| Token/JWT | 设置过期时间（Access Token ≤ 15min） |
| 身份证/手机号 | 加密存储（AES-256），前端脱敏显示 |
| API Key | 环境变量注入，不硬编码 |

## 文件上传安全

| 规则 | 要求 |
|:-----|:-----|
| 文件类型白名单 | 只允许 `jpg/png/pdf/doc` 等 |
| 文件大小限制 | 普通上传 ≤ 10MB |
| 文件名重命名 | 使用 UUID 重命名 |
| 内容校验 | 校验文件头部魔数 |

## 禁止行为
- ❌ 禁止硬编码密钥、密码、Token
- ❌ 禁止使用 `eval()` 或类似动态执行
- ❌ 禁止将用户输入直接拼接到 HTML/SQL/Shell 中
- ❌ 禁止返回密码/密钥给客户端
- ❌ 禁止使用 `http://`（必须 `https://`）
- ❌ 禁止 CORS 配置 `Access-Control-Allow-Origin: *`

## 方法（Methods）

# 安全编码 - 方法

## 前置条件
- [ ] 已确认项目中使用的加密/哈希库
- [ ] 已确认安全 HTTP 头配置

## 流程概览
```
检查输入 → 处理密码 → 配置认证 → 安全传输 → 审计日志
```

## 1. 密码处理（bcrypt）
```javascript
const bcrypt = require('bcrypt');

// 注册时哈希密码
const hash = await bcrypt.hash(password, 10);

// 登录时验证密码
const isValid = await bcrypt.compare(inputPassword, hash);
```

## 2. JWT 配置
```javascript
const token = jwt.sign(payload, secret, {
  expiresIn: '15m',       // Access Token 短时效
  algorithm: 'HS256'      // 不少于 HS256
});
```

## 3. CSRF 防护
- 使用 Token 验证：每个表单/请求携带 CSRF Token
- 使用 SameSite Cookie 属性：`SameSite=Strict`
- 验证 Referer/Origin 头

## 4. 敏感信息脱敏
```javascript
function maskSensitive(data) {
  if (data.password) data.password = '***';
  if (data.token) data.token = data.token.slice(0, 4) + '***';
  if (data.phone) data.phone = data.phone.replace(/(\d{3})\d{4}(\d{4})/, '$1****$2');
  if (data.email) data.email = data.email.replace(/(.{2}).*(@.*)/, '$1***$2');
  return data;
}
```

## 5. 依赖安全
```bash
# 每周检查依赖漏洞
npm audit
```

## 技巧（Tips）

# 安全编码 - 技巧

## 1. 环境变量管理
将密钥/密码放在 `.env` 文件，不要提交到 Git。
```bash
# .env（添加 .gitignore）
API_SECRET=xxx
DB_PASSWORD=xxx
```

## 2. JWT 密钥定期轮换
每 90 天更换一次 JWT 签名密钥，旧密钥保留 24 小时过渡期。

## 3. CSP 策略逐步收紧
从宽松策略开始，通过监控发现违规逐步收紧：
```
Content-Security-Policy: default-src 'self'; script-src 'self' 'unsafe-inline';
→
Content-Security-Policy: default-src 'self'; script-src 'self';
```

## 4. 依赖安全检查
```bash
# 加入 CI 流程
npm audit --production
# 查看过时依赖
npm outdated
```
