---
title: "Lovable 数据暴露：Supabase 权限修复验收"
canonical: https://wavect.io/zh/blog/lovable-supabase-data-exposure/
language: zh
description: "Lovable 数据泄露修复后如何复测？用可下载的 PostgreSQL 示例检查 Supabase 权限，区分本地策略结果与已部署接口验证，并保留允许、拒绝及写入证据。"
image: "https://wavect.io/img/blog/headers/header_lovable-supabase-data-exposure.png"
author: ["Kevin Riedl"]
published: "2026-11-04"
updated: "2026-11-04"
reviewed: "2026-11-04"
---

# Lovable 数据暴露：如何验证权限修复？

[**返回**](/zh/blog/overview/)

[![Kevin Riedl](/img/team/kevin.webp)](/zh/team/kevin-riedl/)

[Kevin Riedl](/zh/team/kevin-riedl/) https://linkedin.com/in/wsdt

16 分钟 阅读 · 2026年11月4日 最近审核 2026年11月4日

[**下一篇**](/zh/blog/lovable-bolt-replit-app-due-diligence/)

要点速览

验收 Lovable 权限修复，要同时验证允许和拒绝的请求。先明确记录、字段及写操作的权限，运行本地策略回归测试，再用真实应用身份复测已部署的数据接口。保留修复版本、正向对照、拒绝结果和未测范围。扫描通过或本地测试通过，都只能说明各自检查范围内的结果。

收到安全警告后，你修改了数据库策略，自己的账号仍能正常使用。关闭问题前，还要确认其他客户是否能读到你的私有记录，以及未登录请求是否会获得本不该访问的数据。

**验收 Lovable 应用的权限修复，先定义预期权限，用合成记录测试允许与禁止的操作，再以真实应用身份，对已部署的数据接口重复测试。**保留修复前后的证据。本地策略测试通过，只能验证特定规则；生产环境的访问行为仍须单独复测。

**核查日期：2026年11月4日。**下文的事件数字来自研究发布者。我们另行运行的示例使用合成数据和本地 PostgreSQL 策略。部署环境复测部分是建议流程，适用于你拥有或获准评估的环境。

**独立性与商标声明:** 本页由 Wavect 发布，Wavect 自身也是服务商，因此我们对本页存在商业利益。我们与本页提及的其他公司没有关联，未获得其背书，也不是其合作伙伴；所有第三方公司名称、品牌与商标均归各自所有者所有。关于其他服务商的陈述来自公开可查的来源，主要是其自己发布的页面，以本页标注的核查日期为准，此后可能已经发生变化。做决定前请自行直接核实。本页依据我们所知的情况撰写，并力求保持客观。如果你认为其中有不准确或不公平之处，请写信告诉我们，我们会更正： [office@wavect.io](mailto:office@wavect.io)

## Lovable 数据泄露报告说明了什么？

[Crissy Field 的 11 月研究报告](https://www.crissyfield.de/research/lovable-en/) 描述了部分 Lovable 应用中无需登录即可读取数据的情况。研究从 2025 年 12 月至 2026 年 9 月的 Common Crawl 存档中识别项目；这些数字更新了 Handelsblatt 11 月 2 日报道所用的统计，各项数量对应不同的样本子集。

| 样本阶段 | 数量 |
| --- | --- |
| 识别出的项目 | 159,041 |
| 使用 Supabase 的项目 | 34,545 |
| 页面加载时返回记录的网站 | 24,664 |
| 进一步读取中发现含邮箱记录的网站 | 7,403 个，涉及 10,560 张表 |

报告中的 30% 指 24,664 个网站中的 7,403 个，**不是已确认的数据泄露率**。含邮箱的记录可能是公开联系方式或测试数据，样本也不具有总体代表性。Lovable 自有数据库产品未纳入研究。

报告举例包括：一家德国生活方式论坛的逾 200,000 条消息；一家服务商逾 1,000 条含护照号码的身份资料记录；以及销售记录中的支付信息。报告没有列明支付卡字段，也无法确认数据是否遭到滥用。这些结果不能判断你的应用是否暴露数据或目前是否已修复。

## 这与此前的 Lovable 聊天记录事件是同一回事吗？

Lovable 的 4 月聊天记录事件涉及构建平台内的项目访问，不是已部署应用的数据库访问。Lovable 在 [4 月 22 日事件说明](https://lovable.dev/blog/our-response-to-the-april-2026-incident) 中描述了一次回归问题：2 月 3 日至 4 月 20 日，已登录的 Lovable 用户持有公开项目链接，就可能读取该项目的源码和构建对话。

Lovable 表示已经修复该问题，私有项目和 Lovable Cloud 当时不受影响。这份声明不能替你验证已部署应用的数据权限。

| 访问边界 | 要回答的问题 | 可用证据 |
| --- | --- | --- |
| 编辑器中的项目 | 谁能打开源码、构建对话和未发布的内容？ | 项目成员与可见性设置 |
| 已发布网站 | 谁能访问已部署页面？ | 发布访问配置，以及使用预期身份访问的结果 |
| 应用数据 | 调用者能访问哪些记录、执行哪些操作？ | 实际后端响应与操作后的数据库状态 |

我们的 [Lovable 应用尽职调查指南](/zh/blog/lovable-bolt-replit-app-due-diligence/) 覆盖更广泛的所有权与交付准备度审查。这里的复测解决一个具体问题：某项明确的数据访问问题是否达到关闭条件。

## 有登录页面，为什么数据库记录仍可能被读取？

登录页面控制应用界面，每个请求能读取哪些数据仍须由后端约束。浏览器直接连接 Supabase 时，隐藏页面或用 JavaScript 筛选列表，都不能证明数据库授权有效。要测试数据请求本身，包括没有登录用户时的行为。

[Supabase API 密钥指南](https://supabase.com/docs/guides/getting-started/api-keys) 区分了 publishable key 与用户身份。公开客户端可以使用 publishable key。没有用户会话时，请求使用 `anon`；登录会话使用 `authenticated`。secret key 和旧版 `service_role` 凭据涉及能绕过 RLS 的高权限访问，须另行控制。

**行级安全（RLS）是 PostgreSQL 用来限制操作可访问哪些记录的机制。**Supabase 的 [RLS 指南](https://supabase.com/docs/guides/database/postgres/row-level-security) 将表级授权与行策略分开：前者决定能否对表执行某种操作，后者限制该操作可访问哪些行。两者都要检查，移除前端按钮不会改变这些权限。

例如，列表查询带上当前用户 ID 后，界面可能只显示正确的记录，但范围更大的查询仍会返回更多数据。我们建议保持调用者身份不变，改为请求其他记录。即使界面从未提供这种操作，后端也应执行记录所有权检查。

## 权限测试必须验证哪些行为？

权限测试要验证：在明确的身份下，允许的操作能够成功，禁止的访问无法成功。先准备两个合成用户及各自的私有记录，定义可访问的字段和操作。否则，测试即使准确验证了策略，也可能验证的是一条不符合产品要求的规则。

| 调用者 | 读取范围 | 允许的修改 | 必须拒绝 |
| --- | --- | --- | --- |
| 未登录访客 | 不能读取私有记录 | 不能修改这张私有表 | 读取、创建或修改私有记录 |
| 用户 A | A 获准访问的字段 | A 获准编辑的字段 | 读取 B 的记录、以 B 的身份写入或转移所有权 |
| 用户 B | B 获准访问的字段 | B 获准编辑的字段 | 针对 A 执行上述操作 |
| 后台任务 | 仅限文档明确的任务范围 | 仅限文档明确的任务范围 | 未验证调用者，就按其任意指定的记录执行操作 |

将有意公开的内容作为独立的正向用例。如果目录本就应该公开，它仍应允许读取。私有数据则先验证所有者能读到预置记录，随即检查其他用户无法读取。否则，空表或故障环境可能让所有拒绝断言都显得成功。

访客账号也要单独区分。 [Supabase 匿名登录](https://supabase.com/docs/guides/auth/auth-anonymous) 会创建使用 `authenticated` 角色的 Auth 用户，其 JWT 带有 `is_anonymous` 声明。如果业务只允许永久账号访问，仅检查该角色不够，还要加入相应策略条件和测试身份。

团队和组织场景需要按真实的成员关系、角色规则授权，不能只套用简单的所有者规则。加入一个已被移除的成员作为测试身份。先确定成员移除后哪些后台任务仍有权限，再验证这个决定，不要默认所有访问都会以同一种方式失效。

## 本地 PostgreSQL 回归测试得到了什么结果？

我们的本地 PostgreSQL 测试复现了越权读取、两种不完整的修复，以及同时约束所有者和租户的策略。**记录的 23 项检查全部符合各自预期。**这也包括确认故意设置的不安全状态。修正后的策略保留了允许的操作，并拒绝了测试中的跨用户和跨租户访问。

运行环境为 Node.js 24.22.1 和 `@electric-sql/pglite` 0.5.15，引擎返回的版本是 PostgreSQL 18.6。 [PGlite 提供内存中的 PostgreSQL 运行环境](https://pglite.dev/docs/) 。示例预置三条笔记：Alice 和 Bob 属于租户 A，Carol 属于租户 B，每人各有一条。

| 策略状态 | 未登录读取行数 | Alice 读取行数 | 结果含义 |
| --- | --- | --- | --- |
| 关闭 RLS，保留读取授权 | 3 | 3 | 私有记录的访问限制失效。 |
| 开启 RLS，未创建策略 | 0 | 0 | 拒绝检查通过，但获准的所有者也无法读取。 |
| 已认证用户读取策略使用 `USING (true)` | 0 | 3 | 挡住了未登录请求，其他用户的记录仍可被读取。 |
| 同时限制所有者与租户 | 0 | 1，且正是 `alice-note` | 所有者能成功读取，结果不含 Bob 或 Carol 的笔记。 |

每次操作前，测试程序都断言实际生效的 PostgreSQL 角色、用户 ID 和租户 ID。Bob 和 Carol 各自只读到自己的预置笔记。给 Alice 身份配上错误租户后，结果为零行。这些正向对照能区分权限限制确实有效，还是数据库为空或根本无法访问。

下面是示例中的原样策略代码。**`fixture.uid()` 和 `fixture.tenant_id()` 读取的是测试程序控制的 SQL 设置。**它们只为本地测试代入身份，不是 Supabase Auth 函数，也不会验证 JWT。这段代码不是生产迁移方案，也未验证租户成员关系是否可信。

```
DROP POLICY signed_in_read ON public.notes;
CREATE POLICY private_notes ON public.notes FOR ALL TO authenticated
  USING (owner_id = fixture.uid() AND tenant_id = fixture.tenant_id())
  WITH CHECK (owner_id = fixture.uid() AND tenant_id = fixture.tenant_id());
```

Alice 获准执行的更新、插入和删除各返回一条预期记录。更新 Bob 或 Carol 的笔记，以及删除 Bob 的笔记，都返回零行。修改所有者、修改租户，或替 Bob 插入笔记，则触发 SQLSTATE `42501`。每次写入被拒后，程序都比较整张表的快照，确认数据未变。

另一个拥有 `BYPASSRLS` 的角色，即使携带 Alice 的测试身份，也能读取全部三条记录。我们还故意再次关闭 RLS：所有者断言检测到了多出的记录；重新启用 RLS 后，结果恢复为一条。这证明回归检查能对实际策略变化作出反应。

[下载策略回归测试示例及运行结果](/downloads/lovable-supabase-data-exposure-fixture.zip) ，解压后执行：

```
npm ci --ignore-scripts
npm test
```

下载包包含依赖锁文件和 `results.json`。测试以受控的本地身份检查 PostgreSQL 授权与策略，未验证 Supabase Auth、JWT、PostgREST、线上 HTTP 响应、视图、存储或 Edge Functions。你仍须按应用的实际范围完成下文的部署环境复测。

## RLS 已启用，为什么修复后仍会越权？

表启用了 RLS，仍可能按错误规则放行请求。检查所有适用的策略与权限，再测试其他数据入口和返回字段。修复既要保留获准操作，也要限制写操作能够存入的新值。

PostgreSQL 的 [行策略文档](https://www.postgresql.org/docs/18/ddl-rowsecurity.html) 说明，宽松策略通过 `OR` 组合。如果仍保留适用的全放行策略，再增加一条只允许所有者的策略，也不会收窄访问范围。文档还说明，超级用户、`BYPASSRLS` 角色以及通常情况下的表所有者，不适合代替普通调用者做测试。

行权限与字段权限要分别设计。 [Supabase 列权限指南](https://supabase.com/docs/guides/database/postgres/column-level-security) 指出，RLS 不决定获准记录中的哪些列可以访问。我们建议将公开资料字段与内部记录分开，或专门设计列权限。还要检查表级授权是否仍允许访问你打算限制的列。

经过函数调用，实际使用的权限也可能变化。Supabase 文档说明， [`security definer` 数据库函数](https://supabase.com/docs/guides/database/functions) 使用函数所有者的权限。限制谁能执行函数，不会自动限制它返回哪位用户的记录。要审查函数体，并测试调用者实际收到的结果。

不要只为恢复出错的页面，就扩大策略的放行范围。先确认原因是缺少授权、所有权条件不符、身份错误，还是部署环境不对。修复真正的原因，才能恢复允许的业务操作，同时避免重新开放原来的越权入口。

## 如何对已部署的应用进行权限复测？

使用真实应用身份和合成记录，对问题范围内的每个已部署数据入口进行复测。记录响应及任何持久化变更。这也会检查会话处理、配置，以及当前实际服务用户的代码。

Supabase 的 [测试概览](https://supabase.com/docs/guides/local-development/testing/overview) 区分了数据库测试和通过应用客户端执行的应用层测试。同一组允许与拒绝用例应在两层都执行。Git 中的迁移脚本可以说明修改意图，还要确认目标环境已经应用了它。

1. **确认目标环境。** 记录项目、部署版本、迁移和获准测试的路径。A、B 与未登录请求分别使用独立浏览器配置或客户端，避免残留会话悄悄改变调用者身份。
2. **预置受控记录。** 为 A、B 设置一眼可区分的合成值。保留一次获准读取，证明目标记录确实存在、接口可以正常工作。不要为取证收集无关的客户数据。
3. **测试读取与写入。** 检查列表、单条记录请求，以及范围内实际使用的创建、更新和删除操作。核对返回字段。写入被拒后，确认原始记录没有变化。
4. **保存结果。** 保留经过脱敏的请求、响应、实际生效的身份、行数及操作前后状态。分别记录缺失或过期会话的行为，以及会话有效但用户无权访问时的行为。

| 数据入口 | 为什么需要单独检查 | 应保留的证据 |
| --- | --- | --- |
| 数据库视图 | [视图所有权与 `security_invoker`](https://www.postgresql.org/docs/18/sql-createview.html) 会影响底层查询使用谁的权限。 | A/B 身份通过视图及底层表访问的结果 |
| 文件存储 | [对象访问策略](https://supabase.com/docs/guides/storage/security/access-control) 控制存储操作，但 [公开存储桶允许公开下载](https://supabase.com/docs/guides/storage/buckets/fundamentals) 。 | 受控对象的列表、下载和上传行为是否符合预期 |
| Edge Function | [函数认证方式与所用客户端](https://supabase.com/docs/guides/functions/auth) 决定查询采用调用者权限还是高权限。 | 已验证的调用者、获准操作和返回记录的范围 |
| 导出、后台任务或订阅 | 产品可能通过另一条路径提供相同记录。 | 约定范围内的所有权检查与对应输出 |

纳入应用实际开放的数据入口，未测试的部分继续保持未完成状态。我们的 [Vibe Coding 软件审计指南](/zh/blog/vibe-coded-software-audit/) 说明了如何将这类访问边界转化为约定的评估范围和交付物。

## Lovable 安全扫描检查哪些内容？

Lovable 的 Quick 和 Deep 安全扫描都会检查代码与配置，覆盖范围不同。将扫描发现与权限矩阵一起评估。扫描无法替你定义全部业务规则，也不能证明已部署环境中的 A/B 测试已经执行。

[当前安全功能文档](https://docs.lovable.dev/features/security) 说明，Quick 在发布时检查数据库访问设置、已知依赖漏洞和无需认证即可访问的 MCP 服务。Deep 增加应用代码分析，也包含 Quick 的检查。

内置扫描分析代码与配置，可选的运行时渗透测试是另一项功能。Deep 可按需运行，也可通过 Enterprise 定时任务运行，或在发布允许未认证访问 MCP 的应用时触发。

[项目 Security 视图](https://docs.lovable.dev/features/security-view) 将发现的问题关联到具体代码版本。刷新过期扫描，并检查被忽略的问题，它们不计入待处理数量。“No issues found”只表示最近一次扫描没有发现问题；文档明确说明扫描器无法发现全部风险。严重问题是否阻止发布，取决于工作区控制设置。

把扫描时间和已审查的问题与复测证据一起保存。审查自动生成的策略修改，并重新运行回归测试。无论改动由人还是助手完成，都使用相同的验收标准。

## 如果机密数据已经能被越权读取，该怎么办？

如果你的应用已经向未授权调用者返回机密数据，先限制相关访问路径，并让安全和数据保护负责人参与处理。我们建议区分即时控制与后续调查：限制访问可以阻止进一步读取，但要判断此前是否有人访问过，还需要复测结果之外的证据。

在可能破坏调查线索的修改之前，保存相关配置、部署时间线和可用日志。记录问题涉及的数据与操作。敏感证据应存放在受控位置；问题跟踪系统通常只保留合成数据复现步骤或经过脱敏的材料。

与系统负责人共同选择措施：限制暴露的函数、撤销意外授权、暂停受影响功能，或修正策略。如果高权限凭据已经暴露，除了消除暴露原因，还要按服务提供方的轮换流程停用旧凭据。公开的 publishable key 则按其预期用途处理。

修复后返回空结果，不能证明此前一直安全。保留的证据要区分发现问题、限制访问生效，以及部署环境复测通过的时间。负责事件处理的团队才能依据实际情况评估通知等义务。

## 什么条件下可以关闭这项权限问题？

只有在已部署范围内，约定的允许与拒绝用例都符合预期、正常业务仍可运行，且证据能对应到所测改动和调用者，才关闭这项权限问题。如果只有 RLS 已开启的配置、管理员查询成功或扫描全绿，却没有应用层复测，我们会继续保留问题。

| 记录项 | 需要保存的内容 |
| --- | --- |
| 预期访问边界 | A 可以读取和编辑自己私有记录中获准的字段；B 与未登录调用者不能。 |
| 所测改动 | 部署版本、数据库迁移，以及相关函数或策略定义 |
| 实际行为 | A/B/anon 的实际响应、返回字段、受影响行，以及写入被拒后数据未变的结果 |
| 剩余范围 | 未测路径、身份类型、部署差异和后续负责人 |
| 关闭决定 | 审查人、测试日期及关闭的具体问题，不作整个应用安全的结论 |

[Cedars 评估案例](/zh/case-studies/cedars/) 介绍了我们在文档、QA 和范围明确的技术评估方面的工作。开工前先约定所需证据。我们的 [渗透测试服务](/zh/services/penetration-testing/) 可为正在运行的应用确定获授权的评估与复测范围。

完整的上线决策可参考 [软件发布 QA 检查清单](/zh/software-development-guide/software-qa-checklist-before-launch/) 。对这项权限问题，要在同一个部署版本上确认允许的请求成功、禁止的请求失败，保留两类结果后再关闭问题。

## Lovable 数据访问权限复测常见问题

### authenticated 会排除 Supabase 匿名账号吗？

不会。Supabase 匿名登录创建的 Auth 用户仍使用 authenticated 数据库角色，其 JWT 包含 is_anonymous。若产品只允许永久账号访问，应单独执行并测试该条件。还要将此类身份与使用 anon 角色的未登录请求区分，两者对应不同的访问规则。

### 看到 Supabase publishable key，是否说明机密凭据泄露？

publishable key 设计用于公开客户端，仅看到它不能判定机密凭据泄露。检查实际密钥类型及其可访问的数据。secret key 或旧版 service_role 凭据需要另行处理，暴露时应移除并轮换。隐藏 publishable key 无法修复过宽的数据权限。

### 能用管理员连接测试客户权限吗？

需要时可以用管理员权限准备受控数据，再切换到正确的实际角色和身份检查客户操作。数据库表所有者和高权限角色可以绕过普通行策略。管理员查询成功可以证明记录存在，但不能证明面向客户的接口执行了预期限制。

### API 返回空结果，就算拒绝测试通过了吗？

先确认请求到达了正确环境、目标记录确实存在、实际调用者与预期一致，再判断空结果。用获准所有者的请求作为正向对照。写操作还要确认存储状态未变。测试输出应分别记录权限错误、策略过滤后的空结果，以及与权限无关的失败。

### 需要离开 Lovable 重写应用才能修复吗？

一项数据访问问题不应默认以重写解决。先定位暴露路径、修正规则并验证部署后的结果。更广泛的架构或所有权问题可能改变这个决定，但应单独评估维护与所有权需求。更换框架本身不能证明新的权限规则有效。

### 一张 RLS 截图能证明生产环境已经复测吗？

截图可以记录某个配置状态，却无法说明所有适用策略、调用者或数据路径。记录目标部署，再用受控记录执行预期请求。保存允许和拒绝的响应，包括写入结果。将截图作为辅助背景，与这项具体问题的实际行为证据一起保留。

### 下载的测试示例能证明线上 Supabase 应用安全吗？

不能。示例在本地运行环境中，以受控角色上下文验证合成数据的 PostgreSQL 策略行为。它不会通过 Supabase 认证真实用户，也不会测试你的 HTTP API、已部署函数、存储或应用配置。可以参考这些用例，再按约定范围通过真实接口和身份复测。

QA 与生产就绪

## 接下来读什么

可靠生产软件所需的测试、审计、维护与加固。

[从这里开始**AI 生成代码的 QA**](/zh/blog/qa-for-ai-generated-code/)

- [Google 大象金鱼模型：先审方案，再让 AI 写代码](/zh/blog/elephant-goldfish-model-design-review/)
- [LangSmith Trace 保留：采样、评估与成本](/zh/blog/langsmith-trace-retention-sampling-cost/)
- [2026 年奥地利软件开发与 QA 公司：4 家服务商对比](/zh/blog/software-agencies-austria-development-qa/)
- [Ultramarine 1 Flash 文档智能体迁移指南：价格、API 限制与验收测试](/zh/blog/ultramarine-1-flash-api-document-workflows/)
- [Greptile Base、Plus、Apex：如何分配 PR 审查预算](/zh/blog/greptile-base-plus-apex-review-budget/)

[下一篇文章**Google 大象金鱼模型：先审方案，再让 AI 写代码**](/zh/blog/elephant-goldfish-model-design-review/)

[**返回**](/zh/blog/overview/)

[![Kevin Riedl](/img/team/kevin.webp)](/zh/team/kevin-riedl/)

[Kevin Riedl](/zh/team/kevin-riedl/) https://linkedin.com/in/wsdt

16 分钟 阅读 · 2026年11月4日 最近审核 2026年11月4日

[**下一篇**](/zh/blog/lovable-bolt-replit-app-due-diligence/)
