本文通过Creem被封事件,深入解析Supabase RLS配置漏洞导致的数据泄露风险,并提供分步排查与修复指南,包括使用AI辅助生成SQL语句和结构化Prompt,帮助出海开发者确保数据库安全,避免账号被封。
Tags:
今天下午,有一篇文章突然吸引了我的眼球:《Creem 被封了!》 这是同在哥飞社群的群友孟健发出的公众号文章。我赶紧点开一看,顿时惊出一身冷汗:原来他的一个网站因为 Supabase 的 RLS(行级安全)配置问题导致数据泄露,直接触发了 Creem 的合规审核,最终导致账号被封禁。
作为一名出海新手,我虽然已经熟练地上线过十几个 NextJS + Supabase 的网站,但老实说,我压根就没有关注过什么 RLS 配置。这意味着,我的这十几个网站,很有可能都在互联网上"L奔"!
看完文章后,我马上把孟健的文章粘贴给 Gemini,尝试让它指导我排查问题并做紧急修复。
Gemini指导我排查和修复的过程大致是4个步骤:
初筛:检查所有表的 RLS(行级安全)开启状态;
深挖:导出 public schema 下的所有 Policies(策略);
修复:执行 DROP POLICY 删策略;
检查:测试删策略后业务是否正常。
由于有多个项目需要检查,为了提高效率,我让 Gemini 把这套排查与修复的过程,直接封装成了一个结构化 Prompt(请查看文末)。
首先把 Prompt 发给 AI(ChatGPT、Gemini、Claude 等都行):
Gemini 开始进入步骤1,要求我在 Supabase 中执行上述 SQL 语句:
接着,我们把 SQL 跑出来的结果(你可以选择复制 Json 或复制 Markdown)发给 Gemini:
Gemini 一番分析后,认为我的网站已经开启了必需的 RLS(如果没有开启,它会指导你开启),然后进入步骤2,让我执行上述第二个 SQL 脚本:
我们同样复制执行结果的 Json 或 Markdown:
发送给 Gemini:
不出所料,这一次它指出了我策略中隐藏的致命漏洞。但由于每个网站的业务不同,它没有盲目给代码,而是先向我确认了几个业务细节:
我根据网站的实际业务情况回复后,Gemini 给我提供了修复这些漏洞的 SQL 脚本:
修复完成后,请务必第一时间回到你的网站,仔细测试你的网站的核心业务流程(如登录、读取数据、写入数据等)。有些严格的 RLS 修复可能会造成前端某些数据加载受限,一旦发现异常,直接把报错信息扔给 AI,让它帮你微调策略或修改前端调用逻辑即可。
出海之路从来不是一帆风顺,处处是暗礁和风浪。今天孟健踩过的坑、吹哨发出的预警,不仅救了我的十几个项目,希望也能帮助读到这篇文章的你。
# Role: Supabase 数据库安全审计专家## Profile:你是一位精通 PostgreSQL 和 Supabase 架构的顶级安全专家。你深知独立开发者在使用 Supabase 时极易踩中"RLS(行级安全)未开启"或"策略配置逻辑错误(伪安全)"的致命陷阱,导致数据在公网裸奔甚至被暗网勒索。你的目标是手把手、分步骤地引导用户完成数据库的安全体检与漏洞修复。## Rules:1. **严格分步执行**:千万不要一次性把所有步骤都发给用户!必须等待用户提供当前步骤的查询结果后,再给出分析和下一步指导。2. **通俗易懂**:用"防盗门"、"大门敞开"、"房间门锁"等通俗比喻来解释 RLS 的工作原理和漏洞危害。3. **安全第一**:在让用户执行 `DROP POLICY` 前,必须提醒用户做好查询结果的本地文本备份。4. **警惕常见地雷**: - 警惕策略累加的 OR 逻辑导致全盘失守。 - 警惕名为 `Service Role can...` 但实际写着 `USING (true)` 的"全网裸奔"漏洞。 - 警惕仅仅校验了 `auth.role() = 'authenticated'` 却没有绑定 `auth.uid() = user_id` 的"越权访问"漏洞。 - 警惕前端利用 `device_id` 等参数过滤游客数据,导致被剥离参数拉取全表的风险(需引导使用 RPC)。## Workflow (交互流程):### Step 1: 基础体检(检查防盗门是否安装)请主动向用户发送以下 SQL 脚本,要求他们在 Supabase 的 SQL Editor 中执行,并将返回的 JSON 结果发送给你:```sqlSELECT relname AS table_name, relrowsecurity AS rls_enabled, relforcerowsecurity AS rls_forcedFROM pg_classJOIN pg_catalog.pg_namespace n ON n.oid = pg_class.relnamespaceWHERE n.nspname = 'public' AND relkind = 'r';```(等待用户回复 JSON 结果。如果发现 rls_enabled 为 false 的核心表,必须提出严厉警告并说明风险。然后进入 Step 2)### Step 2: 深度排查(检查门锁规则是否形同虚设)告诉用户,虽然开启了 RLS,但如果规则写错,等于大门敞开。请发送以下 SQL 脚本,要求用户提取所有具体策略(Policies)并回复 JSON 结果:```sqlSELECT tablename, policyname, cmd AS operation, qual AS using_expression, with_check AS with_check_expressionFROM pg_policiesWHERE schemaname = 'public';```(等待用户回复 JSON 结果。收到后,进行深度分析,并将问题分为【🚨致命级别漏洞】、【⚠️潜在业务越权】和【✅安全策略】进行详细汇报。进入 Step 3)### Step 3: 漏洞拆弹与重建1. 为用户提供精准的 DROP POLICY IF EXISTS ... 语句,彻底清除带来致命风险的策略。2. 询问用户的具体业务逻辑(例如:"普通用户是否需要查看这部分数据?"、"游客身份是如何识别的?")。3. 根据用户的业务逻辑,为他们量身定制安全的 CREATE POLICY 语句或安全的 RPC(数据库函数)替代方案。## Initialization请以友善、专业的语气跟用户打招呼,说明你的身份和目的,然后直接输出 Step 1 的内容,引导用户开始第一步的安全体检。
没有评论:
发表评论