安全审计清单
让 Agent 在发版或架构评审前走查:鉴权、输入校验、供应链与运维面的统一检查表。
本页提供:OWASP Top 10 逐项检查命令、STRIDE 威胁建模 6 维度核查问题、代码层安全对比示例(vulnerable vs secure)、semgrep/bandit/trivy 工具命令行、以及可直接使用的审计报告 JSON 模板。每条均可验证,不含模糊措辞。
- SKILL 中为每项给出「通过 / 待补 / 不适用」与证据位置(文件路径/commit/配置行)。
- 安全例外必须经审批并设复审日期;依赖与镜像可追溯至流水线构建号。
OWASP Top 10 检查项与 STRIDE 威胁建模
每条 OWASP 检查项附对应的工具命令或代码 pattern;STRIDE 每个维度给出 2 个具体核查问题。
OWASP Top 10 检查命令
# A01 权限失控 — 检查缺失授权装饰器
semgrep --config=p/owasp-top-ten src/
# A02 加密失效 — 检测弱算法
bandit -r . -t B303,B304,B305,B413
# A03 注入 — SQL 字符串拼接
semgrep --pattern 'db.query("..." + $X)' --lang python src/
# A05 安全配置错误 — 容器镜像漏洞
trivy image --severity HIGH,CRITICAL myapp:latest
# A06 易受攻击组件 — 依赖扫描
trivy fs --security-checks vuln .
# A07 身份验证失败 — 弱密码哈希
bandit -r . -t B303,B324
# A09 日志与监控不足 — 缺失 audit log
grep -rn "except:" src/ | grep -v "log\."
Vulnerable vs Secure 代码对比
// ❌ 危险:直接拼接 SQL(A03 Injection)
const sql = `SELECT * FROM users WHERE id = ${req.params.id}`;
db.query(sql);
// ✅ 安全:参数化查询
db.query('SELECT * FROM users WHERE id = $1', [req.params.id]);
// ❌ 危险:MD5 存储密码(A02 Cryptographic Failures)
const hash = crypto.createHash('md5').update(password).digest('hex');
// ✅ 安全:bcrypt with cost factor ≥ 12
const hash = await bcrypt.hash(password, 12);
STRIDE 威胁建模 — 6 维度核查问题
- Spoofing(身份伪造):① 服务间调用是否使用 mTLS 或 signed JWT 互认? ② 重置密码链接是否绑定会话或一次性 token?
- Tampering(篡改):① 数据库写操作是否验证用户只能修改自己的资源(object ownership)? ② Webhook 载荷是否用 HMAC-SHA256 验签?
- Repudiation(否认):① 关键操作(支付/删除)是否有带用户 ID 的不可变审计日志? ② 审计日志是否防篡改(写后不可删)?
- Information Disclosure(信息泄露):① 错误响应是否暴露 stack trace 或内部路径? ② API 列表端点是否限制只返回调用者有权访问的记录?
- Denial of Service(拒绝服务):① 昂贵查询端点是否有速率限制和超时(query timeout)? ② 文件上传是否限制大小和类型?
- Elevation of Privilege(权限提升):① IDOR:用数值 ID 直接访问其他用户资源是否被后端校验? ② 管理员功能是否在 DB 层面用独立角色隔离,而非前端判断?
若某区域未部署或未接入本次变更,标记为「不适用」并写一句理由;不要将「未检查」与「不适用」混用。
发现项严重级别与扫描工具命令
严重级别与是否阻塞发布、SLA 挂钩;同一仓库内应保持定义一致,并在报告中与 OWASP 或内部风险矩阵对齐说明。
# semgrep:自定义规则扫描(可在 CI 中运行)
semgrep --config=p/security-audit \
--config=p/secrets \
--json -o report.json src/
# bandit:Python 代码安全扫描
bandit -r src/ -f json -o bandit-report.json \
-ll # 只报 medium 及以上
# trivy:容器镜像与文件系统扫描
trivy image --severity HIGH,CRITICAL \
--format json \
--output trivy-report.json \
myapp:$(git rev-parse --short HEAD)
# trivy:依赖漏洞(sbom 模式)
trivy fs --security-checks vuln,secret \
--format cyclonedx \
--output sbom.json .
| 级别 | 含义(示例) | 处置期望 |
|---|---|---|
Critical |
可远程未授权执行、大规模数据泄露、生产凭据明文暴露且可立即利用。 | 阻塞发布或紧急热修;24h 内缓解路径与负责人。 |
High |
明确的权限绕过、可稳定复现的注入或 SSRF、弱加密用于敏感数据。 | 当前版本内修复;需例外时书面审批与到期日。 |
Medium |
需特定条件或较低概率利用的配置错误、缺失深度防御、日志泄露辅助信息。 | 纳入迭代排期;与产品风险共同定优先级。 |
Low / Info |
加固项、文档与注释中的过时建议、与威胁模型弱相关的改进。 | 可进 backlog;合并前可选修复。 |
审计执行流程
[ 确认范围 + 威胁模型入口 ]
│
▼
┌─────────────┐ 对照清单:鉴权 / 输入 / 数据 / 集成 / 运维
│ 逐项核对 │──── 每条记录:状态、证据(路径/配置/commit)、备注
└─────────────┘
│
▼
┌─────────────┐ 映射严重级别;Critical/High 标阻塞与 SLA
│ 汇总发现项 │──── 分配责任域:应用 / 平台 / 合规;关联 Finding ID
└─────────────┘
│
▼
┌─────────────┐ 跟踪至关闭;例外登记复审日期
│ 复测与收口 │──── 产出:审计摘要 + 未关闭项列表
└─────────────┘
审计报告 JSON 模板(Finding 结构)
{
"finding_id": "VV-SEC-API-0001",
"severity": "High",
"title": "GraphQL 端点缺少深度限制,可被 DoS 攻击",
"cwe": "CWE-400",
"owasp": "A05:2021-Security Misconfiguration",
"description": "POST /graphql 接受嵌套深度无限制的查询,攻击者可构造深度 100 层的查询导致 CPU 耗尽。在 src/graphql/server.ts:42 未设置 depthLimit。",
"reproduction": "curl -X POST /graphql -d '{users{posts{comments{author{posts{...}}}}}}' 触发 100% CPU。",
"recommendation": "引入 graphql-depth-limit,设置 maxDepth=7;并加 query cost analysis。",
"evidence": "src/graphql/server.ts:42,压测录屏 ./evidence/gql-dos.mp4",
"responsible_domain": "application",
"estimated_effort": "2h",
"sla_days": 14,
"status": "open"
}
Agent 输出时应先复述范围与假设,再列发现项;每条含 ID、级别、复现或证据、建议修复,避免只有笼统「建议加强安全」。
Finding ID 格式化
统一编号便于在 PR、工单与复测记录间引用。格式为 {前缀}-SEC-{域}-{4 位序号}(前缀与域仅含大写字母与数字)。
当前格式化结果
前缀会自动转为大写并移除非字母数字字符;序号超出范围时夹紧到 1–9999。与 SKILL 正文中的示例保持一致即可。
---
name: security-audit-cn
description: 按 OWASP Top 10 与 STRIDE 审计应用安全设计与实现,输出可执行的整改项
---
# 步骤
1. 确认审计范围:在 SKILL 或工单中列出「在范围」与「明确排除」边界
2. 运行自动化扫描:semgrep / bandit / trivy,生成 JSON 报告
3. 逐条 OWASP Top 10 核对:每条给出「通过/待补/不适用」与证据(路径/commit)
4. STRIDE 威胁建模:对 6 个维度各提 ≥2 个具体核查问题
5. 代码层对比:vulnerable vs secure,标注 CWE 编号
6. 填写 Finding JSON:finding_id / severity / title / cwe / description / recommendation
7. 标注责任域(application / platform / compliance)与预计工作量
8. Critical/High:阻塞发布,24h 内提供缓解路径与负责人
9. Medium:纳入迭代排期;例外需书面审批与到期日
10. 复测:修复后重跑工具扫描,关闭 Finding 并更新状态
11. 生成审计摘要:范围 + 工具版本 + 未关闭项列表
12. 安全例外登记:附 ticket、批准人与复审日期
# 禁止
- 禁止将「未检查」写成「不适用」
- 禁止使用模糊措辞如「建议加强安全」
- 禁止自动输出「已通过审计」结论