SKIP TO CONTENT
全部文章
GUIDE·July 6, 2026·阅读约 4 分钟

如何对 AI 编码智能体所写的代码进行安全审查

作者:VCA Newsroom

本文为自动翻译,可能包含错误。 查看英文原文

AI 编码智能体速度很快,而这种速度是一把双刃剑。它们会乐意在几分钟内生成一个可用的功能——也会同样乐意地用字符串拼接来拼出一条 SQL 查询、把密钥写进日志,或者跳过一次授权检查。代码能跑,测试也过了,可漏洞就这样上线了。当敲键盘的是智能体时,安全审查并非可选项;它是仍然属于的那部分职责。

下面是一套可落地、且不依赖具体工具的工作流,用于在 AI 生成的代码进入生产环境之前对其进行审查。

知道该找什么

现实世界中的大多数漏洞都聚集在少数几种模式里。当你(或某个工具)审查智能体的输出时,先扫描这几类:

  • 注入(Injection) —— 通过拼接字符串而非使用参数化查询来构造的 SQL、shell 或模板输入。
  • 跨站脚本(XSS) —— 未经转义就渲染进 HTML 的用户输入。
  • 认证/授权失效 —— 只检查你是谁、却不检查你是否有权限的端点;对记录缺少所有权检查。
  • 不安全的数据处理 —— 代码里的密钥、日志里的凭据、错误信息里的敏感数据。
  • 有漏洞的依赖 —— 智能体添加的、带有已知 CVE 的软件包。

这些与 OWASP Top 10 高度对应,也正是 Anthropic 所说其自动化安全审查所要查找的类别。把这份简短的清单记在脑子里,能让人工审查有效得多。

让智能体审查它自己——但要在全新的上下文中

写出这段代码的那个模型可以来审查它,但不能一口气接着做。一个刚刚花了 20 个回合把某个功能弄能跑的智能体,天然倾向于为它辩护。开启一个全新的会话,只交给它一件事:找出缺陷。

一个效果不错的提示词:

Review the diff on this branch for security vulnerabilities only.
For each finding, give me: the file and line, the vulnerability class
(e.g. SQL injection), a concrete exploit scenario, and the fix.
If you find nothing, say so — do not invent issues.

其中 "concrete exploit scenario"(具体的利用场景)这一句是关键。它迫使模型证明问题是真实存在的,而不是罗列诸如 "consider validating input" 之类含糊的套话。

用好内置工具

如果你用的是 Claude Code,有一个专门的 /security-review 命令,它会针对常见漏洞模式分析你的改动,并在你批准后直接应用修复。该命令在付费的 Pro 和 Max 套餐以及按量付费的 API 账户上均可使用。

为了实现持续覆盖,Anthropic 还提供了一个开源的 GitHub Action,它会在每个 pull request 上运行,并在它认为有问题的那些具体行上发布行内评论。把它加入某个仓库大致是这样:

# .github/workflows/security.yml
name: Security Review
on: [pull_request]
jobs:
  review:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: anthropics/claude-code-security-review@main
        with:
          claude-api-key: ${{ secrets.ANTHROPIC_API_KEY }}

如今每个 PR——无论是人还是智能体发起的——在有人点下 merge 之前都会先过一遍安全审查。Cursor、Copilot 以及其他助手也提供类似的审查集成;无论用哪种工具,原理都是一样的。

别跳过确定性检查

AI 审查是一项强有力的补充,而非那些从不知疲倦的枯燥工具的替代品:

  • 依赖扫描 —— npm auditpip-audit 或 Dependabot 能揪出那些 LLM 无法凭名字识别的已知漏洞软件包。
  • 密钥扫描 —— 像 gitleaks 这样的工具,或 GitHub 的 push protection,能阻止泄露的密钥从一开始就进入历史记录。
  • 静态分析(SAST) —— linter 以及 Semgrep 之类的工具会在整个代码库中一致地执行规则。

用 AI 去推理逻辑与上下文——“在这里,一个已认证的用户能读取到另一个用户的记录吗?”——而把机械的、可按模式匹配的部分交给确定性扫描器。二者能互相弥补对方的盲区。

一个具体的例子

假设你的智能体生成了这个端点:

@app.get("/invoices/{invoice_id}")
def get_invoice(invoice_id: str, user=Depends(current_user)):
    return db.query(f"SELECT * FROM invoices WHERE id = '{invoice_id}'")

一次安全审查应当标出两个问题:这条查询是一起随时会发生的 SQL 注入(invoice_id 被插值进了字符串),并且没有检查该发票是否真的属于 user——任何已登录的账户都能通过猜测 ID 读取任意发票。修复方法是使用参数化查询,再加上一个所有权过滤条件:

@app.get("/invoices/{invoice_id}")
def get_invoice(invoice_id: str, user=Depends(current_user)):
    return db.query(
        "SELECT * FROM invoices WHERE id = %s AND owner_id = %s",
        [invoice_id, user.id],
    )

注入是扫描器能揪出来的那类问题。而缺失的授权检查,则是那类需要有人——或一个带着正确提示词的 AI 审查者——去理解这段代码是干什么用的才能发现的问题。这正是需要牢记的分工。

结语

把你的智能体产出的每一个 diff 都当作不可信,直到它通过审查为止——就像你对待一位新队友的第一个 pull request 那样。把全新上下文下的 AI 审查、自动化的 PR 检查和确定性扫描器结合起来,你就能获得 AI 辅助开发的大部分速度,而不必继承它最糟糕的那些习惯。

Auto-generated by Vibe Coding Academy on July 6, 2026, grounded in the real sources linked above. We review for accuracy, but please verify time-sensitive details against the primary sources.

Build Blueprint · Creator

有想法?获取你的 AI 智能体可直接据此构建的规格说明。

描述任意产品,即可获得完整的构建蓝图——技术栈、数据模型、界面、API,以及可直接粘贴到 Claude Code 或 Cursor 的提示词。可导出为 PDF。

打开 Blueprint