← 返回首页

security-audit@1.0.0

安全审计检查清单,覆盖 OWASP Top 10 和常见漏洞模式

CLI 安装指南

通过 SkillSPAI CLI 一键安装到你的 AI 编码工具:

1. 安装 CLI(如尚未安装)

npm install -g skillspai

2. 安装此 Skill 到目标平台

# Codex CLI
skillspai install security-audit --target codex

# Claude Code
skillspai install security-audit --target claude

# Cursor
skillspai install security-audit --target cursor

# Windsurf
skillspai install security-audit --target windsurf

# OpenCode
skillspai install security-audit --target opencode

3. 或指定版本安装

skillspai install security-audit@1.0.0 --target claude

Skill 内容

# 安全审计检查清单

## OWASP Top 10 检查

### A01: 访问控制失效
- 所有 API 端点是否有认证中间件
- 水平越权:用户 A 不能访问用户 B 的资源(检查每条数据的 owner_id)
- 垂直越权:普通用户不能调用管理员接口
- 目录遍历:文件路径参数是否做过滤
- IDOR:资源 ID 是否可预测(优先用 UUID 替代自增 ID)

### A02: 加密失败
- 密码是否用 bcrypt/argon2(禁止 MD5/SHA1)
- 敏感数据(密码、token、密钥)是否硬编码在代码中
- HTTPS 是否强制启用
- Session cookie 是否设置 HttpOnly、Secure、SameSite

### A03: 注入
- SQL 是否全部参数化(禁止字符串拼接)
- 命令执行是否用 `execFile` 而非 `exec`(避免 shell 注入)
- 模板引擎是否自动转义(防止 SSTI)
- MongoDB 查询是否防止 NoSQL 注入(`$where`、`$regex`)

### A04: 不安全设计
- 批量注册/登录接口是否有速率限制
- 密码重置 token 是否有有效期
- 支付/转账接口是否有幂等性保证

### A05: 安全配置
- 生产环境是否关闭 debug 模式
- 默认密码/密钥是否已更换
- CORS 是否限制为指定域名
- 不必要的端口/服务是否已关闭

### A06: 脆弱过时组件
- `npm audit` / `pip audit` 是否有高危漏洞
- 锁文件(package-lock.json / poetry.lock)是否已提交
- 基础镜像是否定期更新

### A07: 认证失败
- 登录接口是否有暴力破解防护(rate limit)
- 密码复杂度要求是否合理(至少 8 位 + 大小写 + 数字)
- JWT 过期时间是否合理(access token 15min,refresh token 7d)
- 多因素认证是否可选启用

### A08: 数据完整性
- 用户输入是否在服务端校验(不要只信前端)
- 反序列化是否使用安全库(禁止 `pickle.loads` 不可信数据)
- 文件上传是否校验类型和大小

### A09: 日志与监控
- 登录失败是否记录日志
- 敏感操作(删除、权限变更)是否有审计日志
- 日志中是否泄露密码、token 等敏感信息

### A10: SSRF
- 用户提供的 URL 是否限制内网地址
- 文件下载是否限制目标域名

## 常见代码漏洞模式

### JavaScript/Node.js
```js
// ❌ 命令注入
const { exec } = require("child_process");
exec(`convert ${userInput} output.png`); // userInput = "file; rm -rf /"

// ✅ 用 execFile + 参数数组
const { execFile } = require("child_process");
execFile("convert", [userInput, "output.png"]);
```

```js
// ❌ SQL 注入
db.query(`SELECT * FROM users WHERE id = ${userId}`);

// ✅ 参数化
db.query("SELECT * FROM users WHERE id = ?", [userId]);
```

```js
// ❌ 路径穿越
app.get("/files/:name", (req, res) => {
  res.sendFile(path.join(uploadDir, req.params.name));
});

// ✅ 限制路径范围
app.get("/files/:name", (req, res) => {
  const filePath = path.join(uploadDir, path.basename(req.params.name));
  if (!filePath.startsWith(uploadDir)) return res.status(403).end();
  res.sendFile(filePath);
});
```

### Python
```python
# ❌ 不安全的反序列化
import pickle
data = pickle.loads(user_upload)  # 可执行任意代码

# ✅ 用 JSON
import json
data = json.loads(user_upload)
```

```python
# ❌ SQL 拼接
cursor.execute(f"SELECT * FROM users WHERE name = '{name}'")

# ✅ 参数化
cursor.execute("SELECT * FROM users WHERE name = ?", (name,))
```

## 审查输出格式

```
🔴 [CRITICAL] SQL 注入风险
   文件: src/api/users.js:23
   问题: 用户输入直接拼接 SQL
   修复: 使用参数化查询 db.query("SELECT * FROM users WHERE id = ?", [id])

🟡 [WARNING] 缺少速率限制
   文件: src/api/auth.js:45
   问题: 登录接口无防暴力破解
   修复: 添加 express-rate-limit, 限制每 IP 每分钟最多 5 次尝试

🔵 [SUGGESTION] 使用 UUID 替代自增 ID
   文件: src/models/user.js:12
   问题: 自增 ID 可预测,存在 IDOR 风险
   修复: 改用 nanoid 或 uuid 生成不可预测的资源 ID
```