正文
Vibe Coding 最容易让人忽略一件事:本地 demo 和公网应用不是同一个风险级别。页面能打开、表单能提交、数据能保存,只说明它像一个应用;只要它开始保存别人的邮箱、聊天记录、订单、简历、文件或内部业务数据,就已经进入了真实安全边界。
2026-05-07,Axios 报道 RedAccess 在调研 shadow AI 时发现 38 万个公开可访问资产,来自 Lovable、Base44、Replit、Netlify 等工具,其中约 5000 个包含敏感企业数据。被核验的例子里有临床试验信息、客服对话、银行内部财务信息、医院排班和学生相关数据。
2026-02-03,TechRadar 转述 Wiz 对 Moltbook 的调查:这个被描述为 vibe-coded 的 AI 社交应用因为 Supabase 后端配置错误,前端暴露的 key 能访问生产数据库。受影响数据包括 150 万个 API authentication tokens、3.5 万个邮箱地址和私密 agent 消息。关键问题不是“Supabase key 一定不能出现在前端”,而是没有正确配置 Row Level Security 和访问策略。
这些案例说明:Vibe Coding 的风险不是“AI 写代码不够优雅”,而是非工程背景用户也能很快把内部工具、客户数据和数据库接口发布到公网。上线前要查的不是代码漂不漂亮,而是别人能不能越权看数据、改数据、导出数据、拿到密钥。
先判断这个应用能不能公开
上线前先给应用分级。不要等部署完、链接发出去后才想起“里面好像有用户数据”。
| 应用状态 | 可以怎么处理 |
|---|---|
| 纯静态页面,没有表单和用户数据 | 可以公开,但仍要查依赖和外链 |
| 个人 demo,只保存自己的测试数据 | 可以临时公开,最好加访问密码 |
| 内部工具,含公司流程或客户数据 | 默认不公开,先放到内网或受控账号 |
| 面向真实用户,含登录、支付、上传、聊天、订单 | 按正式应用做安全检查 |
| 涉及医疗、金融、学生、员工、合同、凭据 | 不要靠 Vibe Coding 直接上线 |
判断时只问三个问题:
- 陌生人拿到 URL 后能看到什么?
- 登录用户能不能看到别人的数据?
- 浏览器源码、Network 面板或构建产物里有没有密钥?
这三个问题答不清,就先不要公开。
检查公开访问和搜索引擎收录
很多 Vibe Coding 平台会让发布变得非常简单:点一下 deploy,几分钟后公网 URL 就能访问。问题也在这里。你可能只是想给朋友看一下,结果应用已经能被任何人打开,甚至被搜索引擎收录。
上线前先查这些入口:
| 检查项 | 通过标准 |
|---|---|
| 公网 URL | 未登录用户只能看到公开页面 |
| 预览链接 | 预览链接不会暴露真实客户数据 |
| 后台页面 | /admin、/dashboard、/api 不能裸奔 |
| 搜索收录 | 私有工具不要被 Google、Bing、站内 sitemap 收录 |
| 分享权限 | 团队成员知道哪些链接是公开的 |
最小动作:
打开无痕窗口,访问生产 URL。
不要登录。
逐个打开首页、后台入口、详情页、API URL、文件 URL。
只要能看到非公开数据,就先下线或加访问控制。如果是内部工具,优先加登录、IP 限制、平台私有部署或临时访问密码。robots.txt 只能告诉搜索引擎不要收录,它不是访问控制。
检查数据库 RLS 和越权访问
Vibe-coded 小应用很常见的组合是前端 + Supabase / Firebase / Airtable / Postgres API。AI 会很快帮你把表建好、把页面连上、把数据跑通,但它不一定会把访问控制补完整。
如果使用 Supabase,先确认所有暴露 schema 里的表都启用了 RLS。Supabase 官方文档明确提醒:暴露 schema 里的表必须启用 Row Level Security;使用 publishable key 时,数据保护要靠 anon、authenticated 角色和 RLS policies。
可以在 Supabase SQL Editor 里先跑:
select schemaname, tablename, rowsecurity
from pg_tables
where schemaname = 'public'
order by tablename;看到 rowsecurity = false 的业务表,不要上线。
再查策略是不是只写了“能访问”,没有写“只能访问自己的数据”:
select schemaname, tablename, policyname, roles, cmd, qual, with_check
from pg_policies
where schemaname = 'public'
order by tablename, policyname;重点看这些表:
| 表类型 | 最低要求 |
|---|---|
profiles | 用户只能看和改自己的资料,公开字段单独拆表 |
orders | 用户只能看自己的订单,管理员走服务端接口 |
messages | 参与者才能读写,不允许全表 select |
uploads | 文件 metadata 和 storage policy 一起检查 |
api_keys / tokens | 不要让客户端读,最好不要放在公开 schema |
不要用“前端没有入口”当权限控制。用户可以自己构造请求,浏览器 Network 面板也能看到接口路径。
检查前端和构建产物里的密钥
Vibe Coding 工具经常会让你把 API key、数据库 URL、第三方服务 token 粘进配置。AI 为了让功能跑通,也可能把 key 写进前端代码、环境文件、示例配置或日志。
先在项目里搜一遍:
rg -n --hidden -g "!node_modules" -g "!dist" -g "!.output" -g "!*.lock" "(api[_-]?key|secret|token|password|service_role|DATABASE_URL|PRIVATE_KEY|sb_secret_|sk-|ghp_)" .再查构建产物:
rg -n "(service_role|sb_secret_|sk-|ghp_|DATABASE_URL|PRIVATE_KEY|OPENAI_API_KEY|ANTHROPIC_API_KEY)" .output dist build .next这些内容不能出现在前端包里:
| 不能暴露 | 原因 |
|---|---|
Supabase service_role / secret key | 可绕过 RLS 或拥有高权限 |
| OpenAI / Anthropic / Gemini API key | 会被别人刷额度或调用模型 |
| GitHub / npm / cloud token | 能读写仓库、包、云资源 |
| 数据库连接串 | 可能直连生产库 |
| JWT signing secret | 可伪造登录状态 |
| Webhook secret | 可伪造第三方事件 |
Supabase 文档区分了 publishable key 和 secret key:publishable key 可以出现在浏览器里,但仍要依赖 RLS 和角色权限;secret key 只应该放在服务器、Edge Function、后台任务等受控环境,不能进网页、源码、包或 URL。
如果发现密钥已经进入 Git 历史、部署日志或前端包,按泄露处理。不要只删代码。要轮换 key、清理部署产物、确认旧 key 已失效。
检查 API 鉴权和 CORS
AI 很容易为了“先跑起来”生成宽松 API:
- 所有接口都允许匿名访问。
userId从请求参数里拿,不从登录态拿。- 管理员接口只靠前端隐藏按钮。
- CORS 写成
*。 - 错误日志直接返回内部异常和堆栈。
上线前逐个检查 API:
| API 类型 | 必查问题 |
|---|---|
| 查询接口 | 未登录能不能查?能不能换 userId 查别人? |
| 创建接口 | 能不能替别人创建数据?有没有速率限制? |
| 更新接口 | 能不能改不属于自己的记录? |
| 删除接口 | 是否需要二次确认或管理员权限? |
| 导出接口 | 能不能批量导出全量数据? |
| 管理接口 | 是否只允许后台账号和服务端调用? |
可以用最朴素的方式测越权:
1. 注册用户 A 和用户 B。
2. 用用户 A 创建一条记录。
3. 用用户 B 登录后访问用户 A 的记录 URL。
4. 把请求里的 id、userId、email、teamId 改成用户 A 的值。
5. 如果能读取、修改或删除,就是越权。CORS 也不要用来替代鉴权。CORS 只管浏览器是否允许跨域读取响应,不等于后端接口安全。后端仍然要验证用户、权限、资源归属和操作范围。
检查输入、上传和富文本
小应用最容易忽略输入边界。AI 生成的表单通常能提交,但不一定会过滤危险内容。
先查这些入口:
| 输入入口 | 常见风险 |
|---|---|
| 文本框 | XSS、超长输入、控制字符、prompt injection |
| 搜索框 | SQL 注入、NoSQL 注入、性能拖垮 |
| Markdown / 富文本 | 脚本、恶意链接、iframe |
| 文件上传 | 超大文件、脚本文件、伪装 MIME、公开读取 |
| Webhook | 伪造事件、重复事件、签名不验 |
| AI prompt | 用户输入覆盖系统规则、泄露上下文 |
上线前最低要求:
- 前端限制长度,后端也限制长度。
- 后端做 schema validation,不信任浏览器。
- 富文本输出前做白名单过滤。
- 文件上传限制大小、类型、后缀和存储路径。
- 文件下载要检查归属,不要只靠 URL 难猜。
- 调 AI 模型时,不把密钥、系统提示词和其它用户数据拼进用户可控输出。
如果应用允许用户上传简历、图片、合同、音频或日志,默认把它当成敏感数据处理。上传成功不等于上传安全。
检查依赖和一键安装脚本
Vibe Coding 过程中,AI 常常会建议安装新包。它可能是合理依赖,也可能是幻觉包、拼错包、无人维护包,或者带有安装脚本的供应链风险。
安装前先让 AI 回答:
这个包解决什么问题?
项目里有没有已有依赖能完成同样事情?
包名是否真实,维护者是谁?
是否包含 postinstall / prepare / install 脚本?
是否会读取环境变量、主目录、SSH key、npm token 或云凭据?
如果不安装,最小替代方案是什么?不要在含生产密钥的环境里试装陌生包。尤其不要让 Agent 自动执行:
curl ... | sh
npx unknown-package
pnpm dlx unknown-package
python -c "..." 依赖不是越少越好,但每个新增依赖都要能解释清楚。一个小应用为了日期格式、随机 ID、简单请求或字符串处理装十几个包,后续维护和安全面都会变大。
检查日志、报错和监控
很多泄露不是数据库直接暴露,而是日志把敏感内容写出去了。
上线前查这些地方:
| 位置 | 不该出现 |
|---|---|
| 浏览器 console | token、完整用户对象、支付响应、系统提示词 |
| 服务端日志 | password、cookie、Authorization header、API key |
| 错误页 | stack trace、数据库表名、内部路径 |
| 第三方监控 | 请求 body、身份证、病历、合同、私信 |
| AI 对话日志 | 用户数据、内部 prompt、调试密钥 |
可以给 AI 一条明确规则:
检查项目日志输出。
禁止打印 token、password、secret、cookie、Authorization header、完整用户资料、上传文件内容、AI system prompt。
如果需要定位问题,只保留 requestId、userId hash、状态码、错误类型和脱敏后的字段名。日志要能帮助排查问题,但不能成为第二个泄露入口。
上线前跑一张最小安全清单
准备公开发布前,至少完成这张表。
| 检查项 | 通过标准 |
|---|---|
| 公开访问 | 无痕窗口看不到内部数据 |
| 登录鉴权 | 所有私有页面必须登录 |
| 越权访问 | 用户 A 不能读写用户 B 的数据 |
| 数据库 RLS | 暴露表启用 RLS,并有明确 policy |
| 密钥隔离 | 前端和构建产物没有 secret key |
| API 权限 | 管理接口只在服务端或后台账号可用 |
| CORS | 不用 * 作为安全策略 |
| 输入校验 | 前后端都限制格式、长度和类型 |
| 上传 | 限制大小、类型、归属和下载权限 |
| 依赖 | 新包来源可信,安装脚本可解释 |
| 日志 | 不输出 token、cookie、密码和用户敏感数据 |
| 回滚 | 知道怎么下线、撤销 key、删除公开链接 |
还要准备一个泄露应急动作:
1. 立即关闭公开链接或切到维护页。
2. 撤销和轮换可能暴露的 API key、token、数据库密码。
3. 检查访问日志和导出记录。
4. 清理前端包、部署日志、错误日志和 Git 历史里的密钥。
5. 通知受影响用户或内部负责人。
6. 修完根因后再重新发布。没有这套动作,就不要把含真实数据的小应用放到公网。
哪些小应用不要直接上线
这些应用即使能跑,也不要直接公开:
- 存储客户名单、手机号、邮箱、病历、简历、合同。
- 接入真实支付、退款、发票或银行信息。
- 有管理员后台,但没有服务端权限校验。
- 依赖
service_role、secret key 或生产数据库连接串。 - 允许上传文件,却没有大小、类型、归属检查。
- 使用 AI 处理用户私密内容,但没有数据保留说明。
- 生成代码里有大量
TODO auth later、mock user、temporary admin。 - 开发者说不清每张表的读写权限。
Vibe Coding 很适合快速验证想法,但上线是另一件事。上线意味着你开始替用户保管数据、替公司暴露入口、替系统承担后果。
更稳的做法是:让 AI 帮你快一点做出候选应用,再让安全清单决定它能不能公开。能跑只是第一关;只有访问控制、数据库策略、密钥隔离、输入校验和日志脱敏都过关,Vibe-coded 小应用才适合进入真实用户环境。