News Hacker|极客洞察

21 2 天前 skilldeliver.com
🤦Supabase 数据常被公开:public users 表与未启 RLS
把 users 表放 public 不启 RLS,觉得安全?

🎯 讨论背景

讨论源于有人指出大量基于 Supabase(一个以 Postgres 为后端的 BaaS)搭建的项目把用户数据或自建 users 表放在 public schema,并通过 Supabase 的 auto-generated API 暴露,导致数据外泄。Supabase 的认证表默认放在 auth schema 并不对自动 API 暴露,但官方示例又鼓励为应用特定数据在 public 建表以便访问,这要求开发者主动启用 RLS(Row Level Security)和正确权限。评论进一步指出 LLM/低代码生成器(例如 lovable.dev 这类生成 React SPA 的工具)和不熟悉安全的开发者一起放大了误配置的概率。讨论还把问题与 Firebase 的权限问题、Pocketbase 的设计差异以及过去 MongoDB 的暴露事件做了历史和平台层面的对比。

📌 讨论焦点

误放 public users 表 / 未启用 RLS

多数评论指出泄露并非 Supabase 自动创建的,而是开发者为便于通过自动生成的 API 访问而在 public schema 新建 users 表却未配置 RLS(Row Level Security)。官方文档和示例确实提到 Auth schema 不会被自动 API 暴露,若要通过 API 访问用户数据需要在 public 建表,但同时也警告要启用 RLS;问题在于部分人为了方便绕过安全控件把敏感数据放入 public。还有评论补充说官方的 Users 表文档信息不够详尽(例如字段何时被填充、验证状态如何表示),这类文档缺失会导致开发者误判并错误依赖,从而放大风险。

[来源1] [来源2] [来源3] [来源4]

LLM/低代码生成器导致不安全实践

多条评论指出像 lovable.dev 这类基于 LLM 的应用生成器会默认生成基于 Supabase 的 React SPA,常常没有真正后端,促使非技术用户把数据库直接当 API 使用,从而容易忽略 RLS 和权限。有人举例说生成器会生成不合理的自定义实现(比如自建 JS Markdown 解析器而非使用 react-markdown),在尝试设置 webhook 时也可能撤销已做的安全配置,说明这些工具在安全方面不可靠。评论的结论是 LLM/生成器能放大生产力,但并不能替代对安全、架构和 serverless 模式有深刻理解的开发者;工具更多是技能增强而非把不懂安全的人直接变成安全工程师。

[来源1] [来源2] [来源3] [来源4]

架构权衡与替代方案(Pocketbase)

有人从架构角度质疑为何需要在 public 创建新的 users 表:主要是为了存放应用特有的用户元数据,Supabase 的示例也倾向于让开发者在 public 建表以便通过 auto-generated API 访问这些字段,但这把权限与 RLS 的责任交还给了开发者。作为对比,Pocketbase(一个自托管的后端替代方案)在用户数据的建模上不强制开发者建立公开 users 表,某些场景因而更直观。评论还指出 Supabase 自带的 Users 表在字段语义和填充时机上文档不足(例如创建时某些字段显示为已验证),这会让业务逻辑对用户状态的判断变得不可靠。

[来源1] [来源2] [来源3]

历史教训与平台比较(Firebase / MongoDB)

讨论把这个问题放在更大的平台比较和历史教训里:Firebase 同样常因权限配置不当导致数据暴露,但其生态通常鼓励使用 Google auth 等托管登录,从而减少密码哈希泄露的风险。有人把当前情形类比为早年的 MongoDB 配置泄露事件,提醒这类错误并非新鲜事,而是“把数据库当 API”这种模式对不熟悉安全的开发者本身就是一个 footgun。总体观点是:平台设计、文档清晰性和用户教育三者都需要改善,单靠工具或默认配置无法完全避免此类错误。

[来源1] [来源2]

📚 术语解释

RLS(Row Level Security): PostgreSQL 的行级安全机制,允许为表中每一行定义访问规则。Supabase 建议对放在 public schema 的用户相关表启用 RLS,以防通过自动生成的 API 被未经授权的客户端读取或修改数据。

schema(Postgres:public vs auth): Postgres 的命名空间概念。Supabase 将认证相关表放在 auth schema(默认不会通过 auto-generated API 暴露),而 public schema 是默认命名空间且会被自动生成 API 暴露,开发者若将敏感表放在 public 必须自行配置 RLS 与权限。