在浏览器里发现了 Supabase 的密钥?第一个小时该做什么
前端中的 service role 密钥或 secret 密钥,会让任何人完全掌控你的数据库。正确的顺序是:作废、替换、查看日志,再修复根源。
阅读约 5 分钟
你按照我们的 10 分钟 Supabase 自查,在应用的 JavaScript 中搜索 service_role 或 sb_secret_,结果找到了。也可能是有人发邮件告诉你,他发现了这个密钥。无论哪种情况,能够绕过数据库所有安全规则的密钥已经公开了。
这是用 AI 开发的应用上线时可能犯下的最严重的错误,也是最常见的错误之一。好消息是:只要按正确的顺序处理,大约一个小时就能修复。
这个密钥为什么特殊
Supabase 为每个项目提供两类密钥:
| 密钥 | 应该放在哪里 | 能做什么 |
|---|---|---|
publishable 密钥(sb_publishable_…)或旧版 anon 密钥 |
浏览器 | 只能执行 Row Level Security 规则允许的操作 |
secret 密钥(sb_secret_…)或旧版 service_role 密钥 |
仅限服务器 | 一切操作:完全绕过 Row Level Security |
拿到 secret 密钥的陌生人,根本不需要寻找规则中的漏洞。他可以读取所有表、修改任何一行、删除数据,还能从私有存储中下载文件。你的规则对他完全不起作用。
第 0–10 分钟:确认泄露的是哪个密钥
在 Supabase 控制台中打开 Project Settings → API Keys,与你在浏览器中找到的内容进行比对:
- 如果以
sb_secret_开头,就是新版 secret 密钥。可以单独替换它,不影响其他任何东西。 - 如果是以
eyJ开头的长令牌,就是旧版 service_role 密钥。旧版密钥不能逐个轮换,处理方法不同(见下文)。
同时记下这个密钥在哪里被使用:哪个文件、哪个功能。AI 工具之所以把它放进前端,通常是因为某个操作用公开密钥失败了,原因多半是缺少 RLS 规则,于是用绕过 RLS 的密钥走了捷径。
第 10–30 分钟:替换密钥
如果是新版 secret 密钥(sb_secret_)
- 在 API Keys 中创建一个新的 secret 密钥,并用能说明用途的名称命名(例如
edge-functions)。 - 把新密钥配置到服务器代码需要它的所有地方:Edge Functions 的 secrets、托管平台的环境变量、后台任务等。
- 删除泄露的密钥。使用它的请求会立即失败。
如果是旧版 service_role 密钥
- 如果还没有,在 API Keys 页面创建一个 publishable 密钥和一个 secret 密钥。
- 把前端的 anon 密钥换成 publishable 密钥,把服务器代码中的 service_role 换成 secret 密钥,然后部署。
- 在同一页面停用旧版 API 密钥。这会同时停用 anon 和 service_role 两个密钥,所以必须先完成第 2 步。如果遗漏了某个客户端,Supabase 允许重新启用,因此这一步是可以撤销的。
Supabase 本来就在逐步淘汰旧版密钥,所以这项工作迟早都要做。
第 30–45 分钟:彻底把密钥移出前端
替换密钥可以止住泄露,但依赖它的代码现在会出错。不要为了修复而把新的 secret 密钥再放回浏览器,而是把这部分工作移到服务器上:
- 使用 Supabase Edge Function 处理需要高权限的操作(发送邀请、写入管理表、调用付费 API)。Edge Functions 可以从运行环境中读取项目的 secret 密钥,无需粘贴到代码里。
- 或者编写一条 RLS 规则,只允许该页面真正需要的操作。AI 之所以动用 secret 密钥,往往是因为某张表开启了 RLS,却没有为登录用户设置任何规则。有了正确的规则,就不再需要 secret 密钥。
然后,在构建后的 JavaScript 中再次搜索 sb_secret_、service_role 以及新密钥的前几个字符。目标是零匹配。
第 45–60 分钟:查明密钥暴露期间发生了什么
你需要知道是否有人用过这个密钥,而这需要趁日志还在的时候查看。
- 在控制台的 Logs 中查看暴露期间的 API 请求:异常的请求量、对应用从不读取的表的请求、使用
select=*的批量下载、不是你执行的删除操作。 - 在 Auth → Users 中检查是否有你不认识的账户,在存储中检查是否有你没有上传过的文件。
- 如果怀疑数据被改动,在做任何其他更改之前,先确认你的套餐包含哪些备份或时间点恢复功能。
Supabase 的日志保留时间取决于套餐,可能很短。请今天就处理,不要拖到下周。
防止再次发生
AI 工具会重复它在你的项目中见过的做法。几个习惯可以防止第二次泄露:
- secret 密钥只放在服务器端的环境变量中,绝不放进框架会发送到浏览器的变量里(在 Vite 中,所有以
VITE_开头的变量都会进入打包文件;在 Next.js 中则是以NEXT_PUBLIC_开头的变量)。 - 每个服务使用一个独立命名的 secret 密钥,这样一旦泄露,只需替换一个。
- 每次发布前,在构建结果中搜索
sb_secret_和service_role,只需几秒钟。 - 当 AI 建议用 secret 密钥来消除某个错误时,要把它当作缺少 RLS 规则的信号。
如果你希望有人检查整个应用,包括密钥、规则、存储和身份验证,我们免费的 Security Check 会以只读方式从外部进行检查,并告诉你应该优先修复什么。
SupabaseAPI 密钥AI 开发的应用
继续阅读
全部文章
应用安全
你用 AI 开发的应用在泄露数据吗?10 分钟完成 Supabase 自查
用 Lovable 或 Bolt 基于 Supabase 开发的应用,经常带着任何人都能读取的数据表上线。本文介绍如何在十分钟内自查,以及应该先修复什么。
阅读约 4 分钟

网站
网站联系表单的邮件为什么会进垃圾箱?SPF、DKIM 和 DMARC 如何解决
网站表单发来的邮件进了垃圾箱,甚至根本收不到?问题通常不在内容,而在发送方式。本文介绍要检查什么,以及需要配置的三条 DNS 记录。
阅读约 5 分钟