開発/設計

Vibe Coding 的 45% 有漏洞。三部曲终章,我把预防的设计全写下来了

AI 生成代码的 45% 存在安全漏洞。整个行业的结构性问题首次被量化的今天,我以三部曲终章的形式,解说如何将预防的设计融入 Vibe Coding。

Vibe Coding 的 45% 有漏洞。三部曲终章,我把预防的设计全写下来了
目次

45%。

这个数字,证明了我写这三部曲的意义。

第一弹追踪了 Lovable(拉瓦布尔)平台上 170 个应用的后门。第二弹介绍了在生成之后进行验证的”Vibe & Verify”(Vibe 与验证)三个步骤。

终章的主题是整个行业的结构性问题。AI 生成代码的 45% 存在安全漏洞。这是 daily.dev(每日开发)的调查首次将 Vibe Coding 的风险量化的数字。

我正在见证”一个事件”变成”行业数字”的瞬间。

三部曲的最终回写”预防的设计”。在发现、验证之后,是”从一开始就不让漏洞产生的机制”。如何在不扼杀 Vibe Coding 速度的前提下确保安全,我想把方法全盘托出。

45% 的真相。安全风险首次以”行业数字”的形式被可视化

AI 生成代码的 45% 存在安全漏洞。92% 的开发者在使用,新代码的 60% 由 AI 生成。问题不在某个特定工具,而存在于编码主流之中。

Lovable 的 10.3% 已经够冲击了。不过那时还有”这只是某一个平台的事”的解读空间。

这次的 45%,可没那么轻松。

根据 daily.dev 的调查,AI 生成代码的 45% 存在安全漏洞。对象不是 Lovable 一家,而是横跨主要 Vibe Coding 工具整体的数据。

来梳理一下规模感。

  • 美国开发者中 92% 日常使用 Vibe Coding
  • 2026 年新代码的 60% 由 AI 生成
  • 其中 45% 存在安全漏洞

把这些数字相乘就能看清。全球新写的代码中相当大的比例,都在漏洞百出。

根据 GitHub(吉特哈布)的 Octoverse 2024,AI 生成代码已占整体的 41%。总量达 256 亿行。CodeRabbit(代码兔)对 470 个 PR 的分析显示,AI 共同编写的代码包含1.7 倍的严重问题

我认为 45% 这个数字,将零散的发现升格为”整个行业的结构性问题”。

三阶段漏斗图,从上至下依次为"92% 使用 AI → 60% AI 生成代码 → 45% 存在漏洞"。上段蓝色、中段橙色、下段红色,可视化风险扩大过程

老实交代一下。45% 的一手出处是 daily.dev 的文章。调查样本规模、漏洞定义的细节,并未完全公开。与其完全照单全收,不如解读为”行业整体风险正在显性化”的趋势,这种姿态才正确。

即便如此,这个数字出现的意义依然重大。“一个应用有漏洞”和”整个行业近一半都有漏洞”,对策的规模完全是两个量级。

三部曲的地图。发现 → 验证 → 预防,看见了什么

第一弹了解”事件”,第二弹获得”验证的范式”,终章加入”预防的机制”完成闭环。这与客户成功的故障响应是同样的结构。

三部曲是偶然开始的。

我记得 3 月底 Lovable 漏洞被报道时的情景。当我读到对 1645 个应用进行扫描、发现 170 个存在漏洞的数据,那一刻就决定必须写成文章,这是起点。这便成了第一弹《170 个后门》

写完之后,“那我自己的代码该怎么确认?“的疑问留在了脑海里。它的答案就是第二弹《Vibe & Verify》。把生成和验证分到不同的会话。让 AI 解释意图。围绕容易出错的情况写测试。我提议用 10 分钟跑完三个确认步骤的方法。

不过,验证只是事后应对。是漏洞已经出现之后再去填补的工作。

看到 45% 这个数字我才醒悟。光靠事后填补根本追不上。我们需要的是从一开始就不让漏洞产生的机制设计。

主题角色
第一弹(4/1)Lovable 170 个后门发现。了解正在发生什么
第二弹(4/14)Vibe & Verify 三步法验证。生成之后如何确认
第三弹(本文)预防的设计预防。从源头不产生漏洞的机制

正因为出身 CS(客户成功),有种结构让我一下就能心领神会。这个流程,与客户成功的故障响应流是同构的。“事故发生 → 根因分析 → 再发防止策”。第一弹是事故报告,第二弹是分析,本文对应再发防止。

仅仅知道问题还不够。仅仅持有验证手段也不充分。只有将预防作为机制实现,Vibe Coding 才能成为”可以放心使用的工具”。

预防设计的三层。从提示词到 CI/CD 一气呵成守护

预防是”提示词 → 模板 → 自动门禁”的三层结构。在维持 Vibe Coding 速度的同时,把安全作为机制嵌入的方法,我来介绍。

听到”预防的设计”可能会觉得很夸张。我一开始也是这么想的。

实际做了一遍,比想象中简单得多。分成三层就便于梳理。

第 1 层:把安全要求烙进提示词

最简便、最有效的方法就是这个。

让 AI 写代码时,仅仅说”做一个用户注册 API”是不够的,第一弹已经讲过这个教训。RLS 未设置就上线的根本原因,正是在这里。

# NG:只传达功能
"做一个用户注册 API"

# OK:包含安全要求一起传达
"做一个用户注册 API。
 要求:
 - 启用 RLS。设置用户仅能读写自己数据的策略
 - API 密钥从环境变量读取(禁止直接写在前端)
 - 用户输入用参数绑定处理
 - 设置速率限制(每分钟最多 10 次请求)"

这种差异是戏剧性的。第一弹介绍的 Lovable 案例,RLS 未设置导致 18000 人的数据泄露。在提示词里多写几行就能防住的问题。

我现在把安全要求的默认项写进了 CLAUDE.md 文件。Claude Code(克劳德代码)会自动加载项目根目录的 CLAUDE.md,这是设计如此。免去每次都要在提示词里写的麻烦,让我十分受用。

# 写入 CLAUDE.md 的安全默认项示例

## 安全要求(全代码通用)
- 创建数据库表时必须启用 RLS
- 密钥从环境变量获取,禁止硬编码
- 用户输入必须先净化再处理
- 需要鉴权的端点必须配置中间件
- 错误响应中不得包含堆栈跟踪

写一次,就会应用于该项目内所有请求。最大的好处是”忘记写安全要求”这个风险本身被消除了。

第 2 层:把 VibeContract 做成安全模板

还记得第一弹介绍的 VibeContract(Vibe 契约)吗?对 AI 而言相当于”合同书”的机制。

那时只停留在概念介绍。这次拿出我实际在用的模板。

# vibecontract-security.yaml
# Vibe Coding 用的安全契约模板

version: "1.0"
project: "my-app"

security_contracts:
  database:
    - "所有表启用 RLS"
    - "策略遵循最小权限原则"
    - "管理员角色的策略单独定义"

  secrets:
    - "API 密钥和令牌从 .env 获取"
    - ".env 文件必须加入 .gitignore"
    - "传递给前端的密钥仅限 ANON_KEY"

  input_validation:
    - "SQL 查询必须使用参数绑定"
    - "HTML 渲染时必须做 XSS 转义"
    - "文件上传必须校验 MIME 类型"

  authentication:
    - "认证端点必须设置速率限制"
    - "令牌有效期不超过 24 小时"
    - "密码必须用 bcrypt 哈希"

把这个 YAML 文件放到项目根目录即可。请求 AI 生成代码时,加一句”按照 vibecontract-security.yaml 的契约执行”。安全要求会自动反映。

要点是采用 YAML 格式。人和 AI 都易读。新成员加入项目时,安全方针一目了然,这是衍生的好处。

第 3 层:用 CI/CD 在部署前拦截漏洞

最后一层是自动化。人会忘。AI 没有指示也会偷懒。所以只能用机制来防。

# GitHub Actions 示例:把安全扫描集成进 CI
# .github/workflows/security-scan.yml

name: Security Scan
on: [push, pull_request]
jobs:
  scan:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      # Supabase RLS 检查
      - name: Check RLS policies
        run: |
          # 从迁移文件中检索 CREATE TABLE
          # 检出未启用 RLS 的表
          TABLES=$(grep -rn "CREATE TABLE" supabase/migrations/ \
            | grep -oP 'CREATE TABLE \K\w+')
          for table in $TABLES; do
            if ! grep -q "ENABLE ROW LEVEL SECURITY" \
              supabase/migrations/*; then
              echo "ERROR: $table 未设置 RLS"
              exit 1
            fi
          done

      # 密钥泄露检查
      - name: Scan for exposed secrets
        uses: trufflesecurity/trufflehog@main
        with:
          path: ./

这个工作流跑起来后,未设置 RLS 的表或密钥泄露会在 PR 阶段就被检出。可以在漏洞抵达生产环境之前就拦住。

三层预防设计纵向排列的结构图。第 1 层"提示词(手动)"→ 第 2 层"VibeContract(半自动)"→ 第 3 层"CI/CD 门禁(全自动)"

不必三层全部引入。即便只做第 1 层的提示词改造,也能消除 45% 风险中相当大的一部分,这是我的切身感受。从适合自己规模的那一层开始就好。

今天就给你的代码做体检。确认是否在那 45% 里的步骤

在第二弹的 Vibe & Verify 三步之外,本次准备了”预防是否在生效”的诊断清单。5 分钟搞定。

就算引入了预防机制,“是否真在生效”不确认一遍是无法安心的。

第二弹写的是生成后的验证。这次是预防的动作确认。请用以下 5 项在自己手头的项目里检查一下。

#检查项检查方法期望结果
1CLAUDE.md 是否有安全要求打开文件目视确认RLS、密钥、输入校验 3 项均有记载
2.env 是否在 .gitignore 内cat .gitignore | grep .env命中
3前端是否暴露了密钥grep -r "sk-|AKIA|stripe_sk" src/不命中
4数据库的 RLS 是否启用在 Supabase(苏帕贝斯)控制台确认所有表均为 Enabled
5CI 是否包含安全扫描检查 .github/workflows/存在扫描用 job

如果 5 项全过,距离那 45% 的漏洞相当远了。哪怕只卡住一项,最好当天就处理。

先把容易踩的坑同步一下。第 3 项的 grep,应当把已构建文件(dist/build/)也纳入检索范围。即便源代码里没写,也有框架会在构建时把环境变量内联展开。Next.js(奈克斯特杰艾斯)的 NEXT_PUBLIC_ 前缀就是典型例子。这类是”以公开为前提”的变量,绝对不能放密钥。

还有一点要注意。第 4 项即便 RLS 显示为”Enabled”也不能掉以轻心。正如第一弹所写,Lovable 2.0 的扫描器只看”是否启用”。“是否正确生效”并未被验证。需要进一步确认策略本身的内容。

“能跑就行”之外的风景。写完三部曲的感想

不追求完美的安全。只填补致命的漏洞就够了。预防的设计不会扼杀 Vibe Coding 的速度,反而让它加速。

我的哲学没变。“先做个能跑的东西”是出发点。

通过三部曲我学到的是,“能跑就行”和”放任漏洞就行”完全是两码事。能跑是大前提。在此基础上,把致命的漏洞从一开始就堵上。

曾经我觉得自己怎么也敌不过专业工程师。这一点至今未变。在架构的深层设计上,我远远赶不上当年遇见的那些高手们。

另一方面,确认自家应用是否有漏洞,并非只有专业人士才能做。在 CLAUDE.md 里写 5 行安全要求。把 VibeContract 的模板复制粘贴。在 CI 里加一个扫描 job。每一项都能在 10 分钟内完成。

看到 45% 这个数字,老实说我有点害怕。

但同时,也感到希望。

因为原因是明确的。RLS 未设置。密钥外泄。输入校验不到位。从第一弹到第三弹,反复出现的都是同一种原因。原因清楚,对策就能明确地立起来。

METR(梅特)的 RCT报告显示,AI 辅助让工作慢了 19%。原因是对 AI 的提案照单全收,导致评审时间增加。我认为引入预防的设计后,验证负荷本身会减少。既然从一开始就生成安全的代码,事后检查的项目自然就少。

预防不是”减慢开发的机制”。是修筑”能高速但也能安全奔跑的道路”的工作。

开始写三部曲的时候,我并不是想说”Vibe Coding 很危险”。我的动机是”想分享如何安全地驾驭它”。Lovable 的 170 个后门也好,45% 的漏洞率也好,我都把它们解读为”进化吧”,而不是”快停下”的信号。

高手工程师寄宿在自己身上的感觉,是真实的。直到现在我依然这样深信不疑。多亏了 AI,曾经一度受挫的我又能写代码了。这种体验,我完全不打算放手。

只是,安全装置要自己装。这就是三部曲的结论。

总结:用三层把 45% 的漏洞堵上

Vibe Coding × 安全三部曲就此完结。

第一弹了解了 170 个后门。第二弹掌握了验证的范式。终章的本文,是把预防的设计以三层组装起来。

  • 第 1 层(提示词):在 CLAUDE.md 写一次安全要求,会自动应用于所有请求。最简便、效果最高
  • 第 2 层(模板):用 VibeContract 定义安全契约。把 YAML 文件放到项目根目录就能运转
  • 第 3 层(自动门禁):在 CI/CD 嵌入安全扫描。RLS 未设置或密钥外泄都会在部署前被拦截

在 45% 的 AI 生成代码存在漏洞的世界里,守护自己代码的责任在自己身上。不必追求完美。堵住致命的漏洞。我认为这就足够了。

通过三部曲,一个信念在我心中变得更强了。把 Vibe Coding 总结为”危险所以不要用吧”的文章,我不想写。我想要证明的是”装上安全装置之后,可以跑得更快”。这次的三层设计,就是答案之一。

三篇都读完的朋友们,请再次接受我的感谢。对所有正在用 Vibe Coding 创造点什么的人,我留下一句”要不要带着安全装置再做一遍?“,就此为三部曲画上句号。


参考链接

ゲン
Written byゲンCS × Vibe Coder

正直、一度エンジニアは諦めました。新卒で入った開発会社でバケモノみたいに優秀な人たちに囲まれて、「あ、私はこっち側じゃないな」って悟ったんです。その後はカスタマーサクセスに転向して10年。でもCursorとClaude Codeに出会って、全部変わりました。完璧なコードじゃなくていい。自分の仕事を自分で楽にするコードが書ければ、それでいいんですよ。週末はサウナで整いながら次に作るツールのこと考えてます。