AI写代码的那些坑:155个项目的血泪教训
AI开发的速度陷阱:代码是出来了,安全呢?
说实话,我们都干过这事。一下午对着 Lovable、Bolt、Cursor 一顿提示词轰炸,吃晚饭前就拿到了一个能访问的网址。感觉就像变魔术一样——平台包办了 hosting,SSL 自动配好,小项目就这么"上线"了。
但有个让人不太舒服的事实,我一直在琢磨:上线快不等于上线安全。作为一个看着"氛围编码"(vibe coding)这场革命发展过来的人,我觉得我们有必要聊聊,这个"下午到网址"的流水线到底漏掉了什么。
最近有个深度调研扫描了155个被开发者公开上线的"氛围编码"应用,其中99个还在线可以扫描。结果呢?一半让人欣慰,一半让人担忧——这些发现应该改变我们对上线前检查清单的看法。
好消息:密钥没漏那么多
让我有点意外的是:只有1%的被扫描应用把真正的密钥泄露到了浏览器端。
没有暴露的 OpenAI API Key 被别人烧钱,没有 AWS 凭证在客户端 JavaScript 里飘着,没有 Stripe 正式密钥等着被人掏空账户。
这说明一件事:现代 AI 编程平台在安全默认配置上确实进步了。你在 Bolt 或 Replit 创建新项目时,平台会引导你把密钥放到 edge functions 里,而不是一股脑塞进浏览器包。这是实打实的好设计。
但1%也不算少——一个泄露的 Key 可能就是五万块的 OpenAI 账单、被黑的 AWS 账号、或者一条 Stripe 争议直接让你的创业项目还没开始就结束了。别当那1%。
没人说的 Supabase 问题
这儿就开始有点意思了。
37% 的在线氛围编码应用都在前端代码里包含了 Supabase 的匿名密钥。 看到这儿先别慌——这其实是正常操作。Supabase 的设计本身就是这样的,anon key 就是公开的,数据安全靠的是 Row Level Security(RLS)策略来保障。
问题在于:RLS 是可选的。表默认是完全开放的。而当你半夜11点还在赶上线deadline的时候,漏掉那个勾选框简直太容易了。
每一个没开 RLS 的表——或者更糟,写了 using (true) 这种懒人策略的表——都相当于拿着公开钥匙给攻击者开门。黑客都不用黑什么,系统就在那儿摆着,人家直接查你数据库就行,因为你忘了一个设置。
我必须强调:被动扫描检测不出 RLS 配置问题。扫描器只看前端,漏洞在后端数据库。上线前必须手动检查,一个表一个表地查。
Firebase 也一样(出现在4%的被扫描应用里)。安全规则不是可选项,而是整个安全模型的基础。
安全头信息:被遗忘的待办清单
如果你从来没听说过 HTTP 安全头,那太正常了。91% 的被扫描应用没有 Content-Security-Policy,88% 可以被任意网站用 iframe 嵌入(这就是点击劫持的入口)。
这些都不是什么冷门漏洞,而是好几年前就是最佳实践的标准加固步骤。只是氛围编码的流水线默认不包括这些而已。
扫描结果的详细数据:
- 91% 缺少 Content-Security-Policy
- 88% 缺少 X-Frame-Options / frame-ancestors
- 37% 缺少 X-Content-Type-Options
- 38% 缺少 Referrer-Policy
- 8% 缺少 Strict-Transport-Security
- 只有5% 配齐了所有安全头
唯一的好消息是:hosting 平台会自动处理 HSTS,这个基本不用操心。但 CSP 的缺口很要命。当 AI 写的组件渲染用户生成的内容,或者集成第三方脚本时,CSP 是你最后一道防线。没有 CSP,XSS 攻击畅通无阻。
上线收尾的差距
这个发现我本来觉得无所谓,结果越想越在意:30% 的氛围编码应用上线时压根没有 Open Graph 标签。
这意味着别人在 X(Twitter)、Discord 或者 LinkedIn 上分享你的产品时,显示的就是一个光秃秃的网址,没有预览图、没有标题、没有描述。就一行文字。2024年了,这么搞看起来很不专业,而且会直接影响点击率。
调研还发现的其他上线日遗漏问题:
- 11% 没有 meta description
- 77% 没有 sitemap.xml
- 安全评分平均是 B-(84分),只有13%拿到 A
这些应用其实不算灾难,就是缺了点打磨。帮你在截止日前冲线的那个速度,也顺手让你忘了加 <meta property="og:title">。
我的5分钟上线前检查清单
看完这个调研之后,我更新了自己的上线清单。以下是真正重要的事项,在你发 Show HN 帖子之前一定要过一遍:
1. 在构建产物里搜密钥
在打包好的输出文件中搜索 sk-、sk_live_、service_role、ghp_。发现任何一个就立刻轮换密钥,搬到 edge function 或者环境变量里。暴露一个 Key 就够你受的了。
2. 审计每一个 Supabase 或 Firebase 表
打开后台,每个公开表都要开 RLS,每个策略都要精确——绝对不要写 using (true)。一个配置错误的表的读权限可能直接暴露你整个用户数据库。
3. 加上这些安全头
Content-Security-Policy: frame-ancestors 'none'
X-Frame-Options: DENY
X-Content-Type-Options: nosniff
Referrer-Policy: strict-origin-when-cross-origin
如果想先测试再落地,可以用 Content-Security-Policy-Report-Only。但最终一定要部署上去。
4. 关闭生产环境的 source maps
你的 *.map 文件对自己是调试神器,对攻击者也是。多数平台都有开关,上线前记得关掉。
5. 加上 Open Graph 元数据
最低限度:og:title、og:description、og:image。你的上线帖子值得在时间线里看起来体面一点。
6. 生成 sitemap.xml
未来的你会感谢现在的自己。多数平台会自动生成——检查一下你的有没有。
更大的图景
我的看法是:氛围编码本身不是问题,问题是"在我机器上能跑"和"能上生产环境"之间的差距。传统开发者靠多年痛苦的部署经历学会了这个差距。氛围编码者学得更快——这其实是好事。
平台在进步,默认配置在变好。但在安全加固变得和配 SSL 证书一样自动化之前,上线前加上这五分钟的检查清单,还是我们作为建造者的责任。
氛围编码的速度是超能力。安全不应该是使用它的代价。
你的上线前安全流程是什么样的?评论区说说你的检查清单补充——我一直在学习改进。