在发布 AI 打造的 Next.js + Supabase 应用前,先做这 7 项安全检查

Dev.to AI 2026-08-09T12:08:22.690788

AI 编程助手可以大幅缩短“从想法到可用应用”的时间。但遗憾的是,它并不会缩小应用的攻击面。AI 生成的代码往往看起来没问题,能通过编译,也能跑通正常流程的测试。真正的危险往往藏在代码背后的假设里:谁有权限调用某个接口、哪些凭据被暴露了、某个用户能不能访问另一个用户的数据。

在发布一个 AI 辅助开发的 Next.js + Supabase 应用之前,我会重点检查下面这 7 个方面。

1. 搜索泄露的密钥

首先检查代码仓库和客户端 bundle 里有没有凭据。在 Next.js 中,任何以 NEXT_PUBLIC_ 开头的变量都可能被打包进浏览器端代码。Supabase 的 publishable key 或 anonymous key 本身就是给客户端用的,但 service-role key 绝对不行。要留意这些情况:

密钥一旦暴露,最稳妥的做法是立即轮换(重新生成),而不是简单地把它从最新提交里删掉。Git 历史、构建产物、日志和部署预览里,都还可能留着原来的值。

2. 在服务端验证授权

把按钮藏起来不等于授权。每一个敏感的路由、Server Action 和 API handler,都应该在服务端验证调用者的身份和权限。永远不要因为前端传了一个用户 ID、组织 ID、角色或归属字段,就直接相信它。

危险写法通常是这样的:

const { userId } = await request.json();

const { data } = await supabase
  .from("documents")
  .select("*")
  .eq("user_id", userId);

这里的 userId 是调用者自己传进来的。正确做法是:从经过验证的 session 或 token 中获取身份信息,再用这个可信身份去查询。

3. 用对抗性思维测试行级安全

启用行级安全(Row Level Security,RLS)只是第一步。对于每一张归用户或租户所有的表,至少要测试四种情况:

未认证的请求会被直接拒绝;插入和更新操作也不能把数据的所有权指派给其他人。注意,SELECT、INSERT、UPDATE、DELETE 可能各自需要独立的策略。针对写入操作,既要确认能修改哪些已有行,也要确认允许写入哪些新值。RLS 测试最有价值的问题往往不是「Alice 能不能读到自己的数据?」,而是「Alice 能不能读取或修改 Bob 的数据?」

4. 在每一处边界校验输入

TypeScript 类型在运行时并不存在。请求体、查询参数、Webhook 载荷、上传文件的元数据,以及 AI 输出的结构化数据,在使用之前都要先经过校验。像 Zod 这类 schema 校验库可以帮上忙,但关键在于:把每一个外部传入的值都当作不可信数据看待。

校验不能只检查数据结构,还要落实这些约束:

5. 加上滥用防护

即便接口需要登录,也照样可能被滥用。对成本高昂或敏感的操作要加频率限制,比如 AI 生成、登录尝试、邮件发送、文件处理和公开表单。同时还要设置请求体大小上限和超时时间。

面向浏览器的 API 要有意识地配置 CORS:不要把通配符来源与携带凭证的请求搭配使用,也不要拿 CORS 当授权机制——它只能约束那些遵守 CORS 规则的浏览器,起不到真正的鉴权作用。

6. 锁好依赖与 CI/CD 流程

应用本身扫描干净,并不代表交付链路就安全。需要确认以下几点:

构建任务会执行依赖里的代码,所以要像对待应用代码一样,把依赖也纳入安全边界。

7. 审查 AI Agent 的权限与指令

Agent 的配置本质上

发布前必须完成的 7 项安全检查

审查仓库指令、工具权限、Hooks、MCP 服务器和自动化命令时,要像审查源代码一样仔细。一个 AI 代理不该因为“这样开发更方便”就拿到生产环境的凭据或破坏性权限。

推荐的做法是:

一份精简的上线前检查清单

在上线之前,确认以下几点:

AI 能加快写代码的速度,但它无法替你判断:哪些假设对你的用户和生产环境是安全的。

你在项目里遇到过哪次安全检查,抓到了最意想不到的问题?

查看原文