看看你的 Supabase 项目向全世界暴露了什么
anon 密钥本来就该公开。真正的保护是 Row Level Security——而唯一能绕过它的那把密钥,绝不能进入浏览器。我们像攻击者一样从外部检查这两点,不碰你的数据。
免费,无需注册。基础检测只发送普通浏览器会发送的请求。
我们检查什么
- 严重免费检测
前端中的 service_role 或 sb_secret 密钥
两者都能完全绕过 Row Level Security。我们搜索页面及其脚本,以打码形式展示密钥,并注明所在文件。
- 严重Pro
用 anon 密钥就能读取的表
验证域名后,我们会对应用用到的每张表发送一次 HEAD 请求,报告任何人能读取多少行。从不获取内容。
- 提示Pro
受 RLS 保护的表
对 anon 密钥返回零行的表也会列出,让你看到策略确实在起作用。
- 提示免费检测
应用连接的是哪个项目
页面中发现的 Supabase 项目和密钥类型——anon 或 publishable 密钥属于预期之内,不算一条发现。
五分钟自己动手检查
我们从外部检查的一切,你都能在自己的控制台和终端里检查。只在你自己的项目上这样做。
列出未启用 Row Level Security 的表
Supabase 控制台 → SQL Editor。如果保留了默认授权,任何 rowsecurity = false 的 public 表都能用 anon 密钥读取。Security Advisor(Advisors → Security)显示的是同一份列表。
select tablename, rowsecurity from pg_tables where schemaname = 'public' order by rowsecurity, tablename;
以陌生人的身份试一试
使用你网站上的 anon 密钥——每个访客拿到的都是同一把。如果这条命令返回了数据行,那么对任何人也一样。
curl 'https://<project>.supabase.co/rest/v1/<table>?select=*&limit=1' \ -H "apikey: <anon key>" \ -H "Authorization: Bearer <anon key>"
确认 secret 密钥从未进入浏览器
在你的线上网站打开 DevTools,在所有已加载的文件中(Cmd/Ctrl + Option/Alt + F)搜索 service_role 和 sb_secret_。只要有一处命中,就要在 Project Settings → API 中轮换密钥,然后把那段代码移到 Edge Function 中。
启用 RLS 并添加策略
只启用 RLS 而不加策略会拦截一切——请添加一条与表的使用方式相匹配的策略。以用户资料表为例:
alter table public.profiles enable row level security; create policy "read own profile" on public.profiles for select using (auth.uid() = id);
你的 AI 能执行的修复方案
报告里的提示词会点名具体的表和确切的问题,并要求你的 AI 启用 RLS,配上与应用使用每张表的方式相匹配的策略。
修复 app.example.com 上的这些问题。 1. 表 "profiles" 向 anon 密钥返回了 1,240 行。 为它启用 Row Level Security,并添加策略,让用户只能 select 自己的那一行(auth.uid() = id)。 2. 表 "orders" 向 anon 密钥返回了 87 行。 启用 RLS;只允许订单的所有者 select。 完成后重新检测:https://scanyoursite.app/zh?check=app.example.com
新表就是新风险
每次迁移都可能新增一张没有策略的表。开通 Pro 后,每次计划检测都会运行数据表检测,新出现的公开表当天就会通知你。
查看方案常见问题
为什么数据表检测需要验证域名?
查询数据库超出了浏览器在页面上的行为范围,所以我们只为所有者执行。验证只需一条 DNS 记录、一个文件或一个 meta 标签。
你们会存储我的数据吗?
不会。我们用 HEAD 请求统计行数,只保存行数和表名。
anon 密钥算泄露吗?
不算。它本来就设计为公开。我们把它作为提示列出,而不是问题。
粘贴网址,大约一分钟拿到清单。
每条发现都会说明它对你意味着什么、该如何修复——或者给你一段 AI 编程工具可以直接执行的提示词。
免费,无需注册。基础检测只发送普通浏览器会发送的请求。