AI生成应用上线前先查密钥与数据权限
文章提供面向AI生成应用的上线前安全检查,重点排查前端构建产物中的秘密密钥,以及Supabase表的行级安全策略。发现泄露时,应先轮换密钥,再将相关调用迁至服务端。
AI 深度解读
用 Lovable、Bolt、Replit 或 Cursor 做出的应用,周末就能跑通演示,但能运行和能接住真实用户,是两件事。作者建议在分享链接前,花一小时检查密钥、数据库权限、支付、认证和恢复能力。
这份清单的价值在于顺序具体:先查浏览器能拿到什么,再验证用户之间能否越权,最后补上支付确认、费用限制和故障恢复。它适合当作上线前的第一轮排查,但作者没有提供对照实验,不能把它当作安全认证。
浏览器拿到的东西,都要按公开资料处理
作者首先检查前端密钥,因为浏览器下载的代码,用户也能查看。在 Vite 中,VITE_ 前缀变量会进入前端 JavaScript;Next.js 对应的是 NEXT_PUBLIC_。如果把 Stripe secret key、OpenAI key 或 Supabase service_role key 放进去,变量名再隐蔽也没有用。
具体做法是打开已部署的网站,查看源码,再搜索 JavaScript 文件里的 sk_、service_role 和 api_key。这些字符串只是排查线索,需要确认找到的是否为真实密钥。
发现真实密钥后,先轮换,再把相关调用迁到服务端函数。
只删掉代码里的密钥,无法收回别人已经复制的内容。
同样要检查 /.env、/.git/config 和项目可能产生的备份文件路径,预期应返回 404 或被阻止访问。构建产物中的 source maps 也要核对,确认没有发布原本不打算公开的源码映射。
数据库开了 RLS,为什么还要建两个账号
Supabase 的 anon key 原本就允许公开,关键在于数据库怎样限制它。作者要求 public schema 下的每张表开启行级安全(Row Level Security,RLS),并配置严格策略。
下面这段 SQL 用来找出尚未开启 RLS 的表:
select tablename from pg_tables
where schemaname = 'public' and not rowsecurity;
要看的是 not rowsecurity:查询结果指出哪些表没有开启 RLS,并不直接证明这些表一定能被匿名读取。作者把结果概括为任何持有公开 key 的人都能读取,表述偏绝对,实际还要结合访问授权检查。
策略也不能停在「已经开启」。作者给出的所有权条件是 using (auth.uid() = user_id),用当前用户身份匹配记录归属;using (true) 则没有提供这种行级隔离。
接下来必须做双账号测试:登录用户 A,复制 A 的某条记录 id;再登录用户 B,尝试读取该记录。B 如果成功,说明权限可能只验证了「已登录」,没有验证「属于谁」。
匿名访问测试和用户间越权测试,检查的是两道不同的门。
作者称这是 AI 生成应用最常见的泄漏,但没有提供样本量或统计数据。可以接受这个测试方法,不必照单接受它的发生频率排名。
支付、认证和恢复,都要走一遍真实流程
支付成功不能由浏览器抵达「感谢购买」页面来决定,因为地址可以手动输入。作者要求通过支付平台的 webhook 确认付款,每个事件都验证签名,处理函数还要具备幂等性,即同一事件重试时,不会重复发放权益。
认证配置也要落到生产环境:身份服务的 Site URL 和允许跳转的 redirect URLs 应指向真实域名,避免通配配置;密码重置、邮箱确认必须用真实邮箱测通。开发环境能收到邮件,不能替代生产验证。
费用风险同样属于上线检查。注册、登录、密码重置,以及发邮件、调用付费 API 的接口,都需要限流;每个付费服务还应设置支出上限或告警。它们分别控制请求量与费用暴露,不能相互替代。
部署层面,作者要求强制 HTTPS,并配置 Strict-Transport-Security、Content-Security-Policy、X-Content-Type-Options 和 frame policy。Vercel、Netlify 可以通过配置文件设置这些响应头,但原文没有给出可直接套用的配置。
最后,自己完成注册、登录、重置密码、付款、删除账号,并打开每个页面。数据库要开启备份,实际测试一次恢复;代码放进 Git,每次让 AI 做大改动前先提交,给失败修改留下回退点。
我的判断
我认同它把注意力放在数据边界和业务流程上。对于前端、全栈开发者,这些问题比「页面看起来是否完整」更容易被演示掩盖,也更适合直接转成上线检查项。
但这是一份经验清单。原文没有证明一小时足够,也没有给出不同工具生成应用的安全对照数据。RLS 查询、密钥关键词搜索、响应头检查都能发现部分问题,无法证明剩下的部分安全。
作者还披露自己开发了免费外部检查工具 DeployVet,称它能覆盖清单中的第 1、2、4、8、9 项。这是产品能力自述,原文没有提供准确率或覆盖率验证。作者也明确承认:外部扫描看不到登录后的内部情况,更无法判断业务逻辑,双账号越权、支付和认证流程仍需手动验证。
相比只跑自动扫描,这份清单补上了人的操作;相比渗透测试,它的范围明显更窄。适合做发布前的最低检查,不能据此宣布应用已经安全。
能拿来做什么
- 给 Vite 或 Next.js 项目加一道部署后检查,搜索前端产物里的敏感字符串,同时访问
/.env、/.git/config,核对 source maps 的发布范围。 - 使用 Supabase 时,先运行 RLS 查询,再用两个真实账号测试记录隔离,分别验证匿名访问和登录后的越权访问。
- 有支付功能时,检查订单状态是否由验签后的 webhook 更新,并测试同一事件重复到达时会不会重复发放权益。
- 每次让 AI 大幅修改项目前先提交 Git,并把生产环境认证流程、付费接口限流、费用告警和数据库恢复列入发布检查。