安全审计技能
对 Web 应用程序代码库执行严格的静态安全审计。生成摘要表(通过/失败/手动审查)和每个发现项的详细块,包含文件:行证据、风险描述和修复代码。
阶段 1 — 堆栈分类
在扫描任何代码之前,通过读取 package.json、配置文件以及 README 来回答以下问题:
- 框架:SvelteKit / Next.js / Express / FastAPI / 等。
- 数据库驱动:参数化(libsql、pg、prisma)对比原始字符串(低级驱动)。
- 认证机制:JWT / HMAC 令牌 / 会话 / OAuth。
- 部署目标:Fly.io / Cloudflare / Vercel / 裸 Node — 决定信任哪个 IP 头进行速率限制和审计日志(
Fly-Client-IP对比CF-Connecting-IP对比X-Forwarded-For);信任错误的头会使攻击者能够伪造其源 IP。 - 文件上传:是/否 — 如果是,文件存储在哪里(本地文件系统、S3 兼容、CDN)。
- 外部出站调用:电子邮件 API、Webhook、媒体获取 — 潜在的 SSRF 面。
在阶段 2 之前,用一段话总结你的堆栈信息。此处错误的假设会导致错误的结论。
阶段 2 — 扫描
必须阅读:'references/security-checklist.md'
不要为针对单端点的审查加载 references/security-checklist.md — 这会扩大任务范围。仅在完整代码库审计时加载。
按顺序处理清单中的每个类别 — 跳过某个组需要在报告中提供书面理由。
对于每个类别:
- 读取相关的源文件。不要凭记忆标记“通过”。
- 如果文件不存在,标记“手动审查”并附上说明。
- 记录裁决(通过/失败/手动审查)和一行证据备注。
如果仓库太大无法读取所有文件,则按风险优先级处理:先处理认证流程和令牌处理,然后是输入/输出边界,最后是依赖配置。注明哪些文件被跳过。
阶段 3 — 分类
审查你的原始扫描笔记。对每个项目应用裁决规则:
- 通过 — 你阅读了相关代码并确认控制措施已到位。引用文件:行。
- 失败 — 你发现了一个已确认且可利用的漏洞。你有一个代码片段。你可以写出修复方案。
- 手动审查 — 该裁决需要运行时上下文、基础设施权限或人工判断(例如“验证此令牌在 Turso 仪表板上具有只读范围”)。
在分配裁决之前,请自问:“我现在可以仅基于我所阅读的内容编写修复代码吗?” 是 → 失败。否 → 手动审查。
不要为了弱化报告而将“失败”降级为“手动审查”。
阶段 4 — 报告
首先是摘要表:
| # | 类别 | 状态 | 备注 |
|---|---|---|---|
| 1 | SQL 注入 | 通过 | 全程参数化 |
| 2 | XSS | 失败 | 用户控制字段上使用了 {@html} — 见发现项 |
| … | … | … | … |
然后,对于每个“失败”和“手动审查”,提供一个发现块:\n
### [N]. 类别 — 失败
**文件:** `src/lib/example.ts:42`
**代码片段:**
cookies.set(name, token, { httpOnly: true }) // ← 缺少 Secure 标志
**风险:** Cookie 在非生产环境中通过纯 HTTP 传输;可被被动中间人攻击捕获。
**修复:**
cookies.set(name, token, {
httpOnly: true,
secure: process.env.NODE_ENV === "production",
sameSite: "lax",
});
“手动审查”块使用相同的格式,但将修复替换为操作,描述人类需要验证的内容以及在哪里验证。
“通过”项目仅出现在摘要表中 — 没有单独的块。
禁止事项
-
绝对不要未经读取文件就标记“通过” 应改为: 读取文件,在证据备注中引用文件:行。 原因: 基于记忆的“通过”裁决会产生虚假的安全感 — 审计的全部意义在于提供证据。
-
绝对不要在没有代码片段的情况下标记“失败” 应改为: 引用确切的有漏洞的代码行。如果找不到代码片段,则为“手动审查”。 原因: 没有证据的“失败”是噪音;开发人员需要确切位置来修复它。
-
绝对不要混淆“失败”和“手动审查” 应改为: “失败” = 你现在可以编写修复方案。“手动审查” = 你不能,并说明原因。 原因: 混淆两者会破坏报告的可执行性。
-
绝对不要跳过阶段 1 的堆栈分类 应改为: 在扫描任何内容之前,先读取
package.json和一个配置文件。 原因: 信任哪个 IP 头、哪种 CSP 方法有效以及哪种认证模型适用都取决于堆栈 — 错误的假设会级联导致错误的裁决。 -
绝对不要报告与项目框架/库不匹配的修复代码 应改为: 使用项目中已有的确切 API 编写修复(例如 SvelteKit 的
cookies.set,而不是res.setHeader)。 原因: 无法编译的通用修复方案会被忽略;针对框架的修复方案才会被合并。 -
绝对不要为尚未读取源文件的类别编写发现块 应改为: 打开文件,读取它,然后编写块。 原因: 没有文件证据的发现块是断言,而非审计 — 当它被证明错误时,会侵蚀整个报告的可信度。
-
绝对不要在大仓库中无声地跳过文件 应改为: 按风险优先级处理(认证/令牌处理 → 输入/输出边界 → 依赖配置),并在报告中明确列出每个被跳过的文件。 原因: 无声的跳过使得审计的覆盖率声明无法验证 — 在不完整的扫描上产生的“干净”报告读起来像是一个虚假的“全部通过”信号。