Supabase Misconfiguration: Readable Tables in 16,326 Databases, Sensitive Data Confirmed in Some Cases
Supabase Misconfiguration: Readable Tables in 16,326 Databases, Sensitive Data Confirmed in Some Cases
Supabase 配置错误:16,326 个数据库表可被读取,部分已确认存在敏感数据
1. Basic Information
1. 基本信息
Article Title: Everything Everywhere: Systemic Data Exposure in Supabase Apps 文章标题: 无处不在:Supabase 应用中的系统性数据泄露
Source: UpGuard Research 来源: UpGuard Research
Publication Date: 2026-09-25 发布日期: 2026-09-25
Severity: High (Readable tables were identified across 16,326 databases, with indicators of PII present in over half. Although unauthorized acquisition by malicious actors has not been confirmed, the exposure of actual data, including plaintext passwords and authentication tokens, has been verified.) 严重程度: 高(在 16,326 个数据库中发现了可读取的表,其中超过半数存在个人身份信息 (PII) 指标。尽管尚未确认恶意行为者进行了未经授权的获取,但实际数据的泄露,包括明文密码和身份验证令牌,已得到证实。)
2. Quick Summary
2. 快速摘要
A review identified 16,326 databases where third parties could read tables with disabled or misconfigured Row Level Security (RLS) via the REST API, after obtaining the Supabase project URL and public key from the JavaScript of published web applications. 一项审查发现,在获取已发布 Web 应用 JavaScript 代码中的 Supabase 项目 URL 和公钥后,第三方可以通过 REST API 读取 16,326 个数据库中禁用了或配置错误的行级安全性 (RLS) 的表。
3. Attack Flow
3. 攻击流程
Reading Tables with RLS Misconfigurations Using Public Client Information 利用公共客户端信息读取存在 RLS 配置错误的表
An attacker obtains the Supabase project URL and public client key (anon key) from the JavaScript code of a public web application. The attacker sends REST queries specifying common table names (such as users) to the PostgREST API endpoint. Even if a table does not exist, error message hints in the API response may reveal the names of other accessible tables. 攻击者从公共 Web 应用的 JavaScript 代码中获取 Supabase 项目 URL 和公共客户端密钥(anon key)。攻击者向 PostgREST API 端点发送指定常见表名(如 users)的 REST 查询。即使表不存在,API 响应中的错误消息提示也可能泄露其他可访问表的名称。
If SELECT permissions are granted on tables exposed via the API and Row Level Security (RLS) is either disabled or misconfigured to permit unauthorized row access, actual data in the database is returned in the response (requests using only the public key without individual user authentication are typically evaluated under the PostgreSQL anon role). 如果通过 API 暴露的表被授予了 SELECT 权限,且行级安全性 (RLS) 被禁用或配置错误导致允许未经授权的行访问,数据库中的实际数据将被返回到响应中(仅使用公钥而无个人用户身份验证的请求通常在 PostgreSQL 的 anon 角色下进行评估)。
If the retrieved table data contains plaintext passwords, authentication tokens, personally identifiable information (PII), or payment-related details, this creates a risk that attackers could exploit them to impersonate legitimate users or conduct further system compromises. 如果检索到的表数据包含明文密码、身份验证令牌、个人身份信息 (PII) 或支付相关详细信息,这将产生风险,攻击者可能利用这些信息冒充合法用户或进行进一步的系统入侵。
4. Attacker Location and Execution Context
4. 攻击者位置与执行环境
Attackers access the target application’s Supabase REST API endpoint directly from any client environment on the internet. No database administrator privileges are required; attackers leverage only the project URL and public key (anon key) publicly distributed for legitimate clients. 攻击者直接从互联网上的任何客户端环境访问目标应用的 Supabase REST API 端点。无需数据库管理员权限;攻击者仅利用为合法客户端公开分发的项目 URL 和公钥(anon key)。
5. Victim and Administrator Visibility
5. 受害者与管理员可见性
Victims: Because these are direct API queries that bypass the legitimate web frontend interface, it is extremely difficult for general users to detect anomalies through the UI. 受害者: 由于这些是绕过合法 Web 前端界面的直接 API 查询,普通用户极难通过 UI 检测到异常。
Administrators: API requests arrive through the same API gateway as legitimate applications. Requests using only a public key without a user-specific JWT token are evaluated under the anon role, while requests accompanied by an authenticated user JWT are evaluated under the authenticated role. Investigations should cross-reference request URIs, source IPs, and response statuses recorded in API logs with database-side audit logs. 管理员: API 请求通过与合法应用相同的 API 网关到达。仅使用公钥而无特定用户 JWT 令牌的请求在 anon 角色下评估,而带有已认证用户 JWT 的请求则在 authenticated 角色下评估。调查时应将 API 日志中记录的请求 URI、源 IP 和响应状态与数据库端的审计日志进行交叉比对。
6. Success and Failure Conditions
6. 成功与失败条件
Success Conditions:
- Easy availability of the target project’s Supabase REST API endpoint URL and public key.
- The target database schema and tables must be exposed to the API, SELECT privileges must exist for the requesting role, and RLS must either be disabled or have policies that unintentionally permit viewing target rows.
- For meaningful information disclosure to occur, actual sensitive data must be stored within the accessible tables.
成功条件:
- 目标项目的 Supabase REST API 端点 URL 和公钥易于获取。
- 目标数据库架构和表必须暴露给 API,请求角色必须拥有 SELECT 权限,且 RLS 必须被禁用或存在无意中允许查看目标行的策略。
- 要发生实质性的信息泄露,可访问的表中必须存储有实际的敏感数据。
Recommended Defense and Mitigation:
- Project URL / API Key: Distribute only public keys to clients and restrict secret keys to the server side.
- PostgREST (Schema Exposure): Restrict API-exposed schemas and exclude unnecessary internal tables from the REST API.
- PostgreSQL Table Grant: Strictly control minimum necessary table access permissions (grants) for each role.
- Row Level Security (RLS): Enable RLS on API-exposed tables and define least-privilege policies based on ownership and authentication attributes.
推荐防御与缓解措施:
- 项目 URL / API 密钥: 仅向客户端分发公钥,并将密钥限制在服务器端。
- PostgREST(架构暴露): 限制 API 暴露的架构,并将不必要的内部表从 REST API 中排除。
- PostgreSQL 表授权: 严格控制每个角色所需的最小表访问权限(grants)。
- 行级安全性 (RLS): 在 API 暴露的表上启用 RLS,并根据所有权和身份验证属性定义最小权限策略。
Ensure the enforcement of Row Level Security (RLS) and the principle of least privilege (grants) across all tables exposed via the REST API. Do not assume that tables created via the SQL Editor, migration scripts, or external APIs are automatically protected; integrate automated verification of RLS settings and permissions into CI/CD pipelines. 确保在所有通过 REST API 暴露的表上强制执行行级安全性 (RLS) 和最小权限原则(授权)。不要假设通过 SQL 编辑器、迁移脚本或外部 API 创建的表会自动受到保护;应将 RLS 设置和权限的自动化验证集成到 CI/CD 流水线中。