本文内容
Lovable 数据暴露:如何验证权限修复?
收到安全警告后,你修改了数据库策略,自己的账号仍能正常使用。关闭问题前,还要确认其他客户是否能读到你的私有记录,以及未登录请求是否会获得本不该访问的数据。
验收 Lovable 应用的权限修复,先定义预期权限,用合成记录测试允许与禁止的操作,再以真实应用身份,对已部署的数据接口重复测试。保留修复前后的证据。本地策略测试通过,只能验证特定规则;生产环境的访问行为仍须单独复测。
核查日期:2026年11月4日。下文的事件数字来自研究发布者。我们另行运行的示例使用合成数据和本地 PostgreSQL 策略。部署环境复测部分是建议流程,适用于你拥有或获准评估的环境。
独立性与商标声明: 本页由 Wavect 发布,Wavect 自身也是服务商,因此我们对本页存在商业利益。我们与本页提及的其他公司没有关联,未获得其背书,也不是其合作伙伴;所有第三方公司名称、品牌与商标均归各自所有者所有。关于其他服务商的陈述来自公开可查的来源,主要是其自己发布的页面,以本页标注的核查日期为准,此后可能已经发生变化。做决定前请自行直接核实。本页依据我们所知的情况撰写,并力求保持客观。如果你认为其中有不准确或不公平之处,请写信告诉我们,我们会更正: [email protected]
Lovable 数据泄露报告说明了什么?
Crissy Field 的 11 月研究报告描述了部分 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 日事件说明中描述了一次回归问题:2 月 3 日至 4 月 20 日,已登录的 Lovable 用户持有公开项目链接,就可能读取该项目的源码和构建对话。
Lovable 表示已经修复该问题,私有项目和 Lovable Cloud 当时不受影响。这份声明不能替你验证已部署应用的数据权限。
| 访问边界 | 要回答的问题 | 可用证据 |
|---|---|---|
| 编辑器中的项目 | 谁能打开源码、构建对话和未发布的内容? | 项目成员与可见性设置 |
| 已发布网站 | 谁能访问已部署页面? | 发布访问配置,以及使用预期身份访问的结果 |
| 应用数据 | 调用者能访问哪些记录、执行哪些操作? | 实际后端响应与操作后的数据库状态 |
我们的 Lovable 应用尽职调查指南覆盖更广泛的所有权与交付准备度审查。这里的复测解决一个具体问题:某项明确的数据访问问题是否达到关闭条件。
有登录页面,为什么数据库记录仍可能被读取?
登录页面控制应用界面,每个请求能读取哪些数据仍须由后端约束。浏览器直接连接 Supabase 时,隐藏页面或用 JavaScript 筛选列表,都不能证明数据库授权有效。要测试数据请求本身,包括没有登录用户时的行为。
Supabase API 密钥指南区分了 publishable key 与用户身份。公开客户端可以使用 publishable key。没有用户会话时,请求使用 anon;登录会话使用 authenticated。secret key 和旧版 service_role 凭据涉及能绕过 RLS 的高权限访问,须另行控制。
行级安全(RLS)是 PostgreSQL 用来限制操作可访问哪些记录的机制。Supabase 的 RLS 指南将表级授权与行策略分开:前者决定能否对表执行某种操作,后者限制该操作可访问哪些行。两者都要检查,移除前端按钮不会改变这些权限。
例如,列表查询带上当前用户 ID 后,界面可能只显示正确的记录,但范围更大的查询仍会返回更多数据。我们建议保持调用者身份不变,改为请求其他记录。即使界面从未提供这种操作,后端也应执行记录所有权检查。
权限测试必须验证哪些行为?
权限测试要验证:在明确的身份下,允许的操作能够成功,禁止的访问无法成功。先准备两个合成用户及各自的私有记录,定义可访问的字段和操作。否则,测试即使准确验证了策略,也可能验证的是一条不符合产品要求的规则。
| 调用者 | 读取范围 | 允许的修改 | 必须拒绝 |
|---|---|---|---|
| 未登录访客 | 不能读取私有记录 | 不能修改这张私有表 | 读取、创建或修改私有记录 |
| 用户 A | A 获准访问的字段 | A 获准编辑的字段 | 读取 B 的记录、以 B 的身份写入或转移所有权 |
| 用户 B | B 获准访问的字段 | B 获准编辑的字段 | 针对 A 执行上述操作 |
| 后台任务 | 仅限文档明确的任务范围 | 仅限文档明确的任务范围 | 未验证调用者,就按其任意指定的记录执行操作 |
将有意公开的内容作为独立的正向用例。如果目录本就应该公开,它仍应允许读取。私有数据则先验证所有者能读到预置记录,随即检查其他用户无法读取。否则,空表或故障环境可能让所有拒绝断言都显得成功。
访客账号也要单独区分。Supabase 匿名登录会创建使用 authenticated 角色的 Auth 用户,其 JWT 带有 is_anonymous 声明。如果业务只允许永久账号访问,仅检查该角色不够,还要加入相应策略条件和测试身份。
团队和组织场景需要按真实的成员关系、角色规则授权,不能只套用简单的所有者规则。加入一个已被移除的成员作为测试身份。先确定成员移除后哪些后台任务仍有权限,再验证这个决定,不要默认所有访问都会以同一种方式失效。
本地 PostgreSQL 回归测试得到了什么结果?
我们的本地 PostgreSQL 测试复现了越权读取、两种不完整的修复,以及同时约束所有者和租户的策略。记录的 23 项检查全部符合各自预期。这也包括确认故意设置的不安全状态。修正后的策略保留了允许的操作,并拒绝了测试中的跨用户和跨租户访问。
运行环境为 Node.js 24.22.1 和 @electric-sql/pglite 0.5.15,引擎返回的版本是 PostgreSQL 18.6。PGlite 提供内存中的 PostgreSQL 运行环境。示例预置三条笔记: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 后,结果恢复为一条。这证明回归检查能对实际策略变化作出反应。
下载策略回归测试示例及运行结果,解压后执行:
npm ci --ignore-scripts
npm test下载包包含依赖锁文件和 results.json。测试以受控的本地身份检查 PostgreSQL 授权与策略,未验证 Supabase Auth、JWT、PostgREST、线上 HTTP 响应、视图、存储或 Edge Functions。你仍须按应用的实际范围完成下文的部署环境复测。
RLS 已启用,为什么修复后仍会越权?
表启用了 RLS,仍可能按错误规则放行请求。检查所有适用的策略与权限,再测试其他数据入口和返回字段。修复既要保留获准操作,也要限制写操作能够存入的新值。
PostgreSQL 的行策略文档说明,宽松策略通过 OR 组合。如果仍保留适用的全放行策略,再增加一条只允许所有者的策略,也不会收窄访问范围。文档还说明,超级用户、BYPASSRLS 角色以及通常情况下的表所有者,不适合代替普通调用者做测试。
行权限与字段权限要分别设计。Supabase 列权限指南指出,RLS 不决定获准记录中的哪些列可以访问。我们建议将公开资料字段与内部记录分开,或专门设计列权限。还要检查表级授权是否仍允许访问你打算限制的列。
经过函数调用,实际使用的权限也可能变化。Supabase 文档说明,security definer 数据库函数使用函数所有者的权限。限制谁能执行函数,不会自动限制它返回哪位用户的记录。要审查函数体,并测试调用者实际收到的结果。
不要只为恢复出错的页面,就扩大策略的放行范围。先确认原因是缺少授权、所有权条件不符、身份错误,还是部署环境不对。修复真正的原因,才能恢复允许的业务操作,同时避免重新开放原来的越权入口。
如何对已部署的应用进行权限复测?
使用真实应用身份和合成记录,对问题范围内的每个已部署数据入口进行复测。记录响应及任何持久化变更。这也会检查会话处理、配置,以及当前实际服务用户的代码。
Supabase 的测试概览区分了数据库测试和通过应用客户端执行的应用层测试。同一组允许与拒绝用例应在两层都执行。Git 中的迁移脚本可以说明修改意图,还要确认目标环境已经应用了它。
- 确认目标环境。记录项目、部署版本、迁移和获准测试的路径。A、B 与未登录请求分别使用独立浏览器配置或客户端,避免残留会话悄悄改变调用者身份。
- 预置受控记录。为 A、B 设置一眼可区分的合成值。保留一次获准读取,证明目标记录确实存在、接口可以正常工作。不要为取证收集无关的客户数据。
- 测试读取与写入。检查列表、单条记录请求,以及范围内实际使用的创建、更新和删除操作。核对返回字段。写入被拒后,确认原始记录没有变化。
- 保存结果。保留经过脱敏的请求、响应、实际生效的身份、行数及操作前后状态。分别记录缺失或过期会话的行为,以及会话有效但用户无权访问时的行为。
| 数据入口 | 为什么需要单独检查 | 应保留的证据 |
|---|---|---|
| 数据库视图 | 视图所有权与 security_invoker 会影响底层查询使用谁的权限。 | A/B 身份通过视图及底层表访问的结果 |
| 文件存储 | 对象访问策略控制存储操作,但公开存储桶允许公开下载。 | 受控对象的列表、下载和上传行为是否符合预期 |
| Edge Function | 函数认证方式与所用客户端决定查询采用调用者权限还是高权限。 | 已验证的调用者、获准操作和返回记录的范围 |
| 导出、后台任务或订阅 | 产品可能通过另一条路径提供相同记录。 | 约定范围内的所有权检查与对应输出 |
纳入应用实际开放的数据入口,未测试的部分继续保持未完成状态。我们的 Vibe Coding 软件审计指南说明了如何将这类访问边界转化为约定的评估范围和交付物。
Lovable 安全扫描检查哪些内容?
Lovable 的 Quick 和 Deep 安全扫描都会检查代码与配置,覆盖范围不同。将扫描发现与权限矩阵一起评估。扫描无法替你定义全部业务规则,也不能证明已部署环境中的 A/B 测试已经执行。
当前安全功能文档说明,Quick 在发布时检查数据库访问设置、已知依赖漏洞和无需认证即可访问的 MCP 服务。Deep 增加应用代码分析,也包含 Quick 的检查。
内置扫描分析代码与配置,可选的运行时渗透测试是另一项功能。Deep 可按需运行,也可通过 Enterprise 定时任务运行,或在发布允许未认证访问 MCP 的应用时触发。
项目 Security 视图将发现的问题关联到具体代码版本。刷新过期扫描,并检查被忽略的问题,它们不计入待处理数量。“No issues found”只表示最近一次扫描没有发现问题;文档明确说明扫描器无法发现全部风险。严重问题是否阻止发布,取决于工作区控制设置。
把扫描时间和已审查的问题与复测证据一起保存。审查自动生成的策略修改,并重新运行回归测试。无论改动由人还是助手完成,都使用相同的验收标准。
如果机密数据已经能被越权读取,该怎么办?
如果你的应用已经向未授权调用者返回机密数据,先限制相关访问路径,并让安全和数据保护负责人参与处理。我们建议区分即时控制与后续调查:限制访问可以阻止进一步读取,但要判断此前是否有人访问过,还需要复测结果之外的证据。
在可能破坏调查线索的修改之前,保存相关配置、部署时间线和可用日志。记录问题涉及的数据与操作。敏感证据应存放在受控位置;问题跟踪系统通常只保留合成数据复现步骤或经过脱敏的材料。
与系统负责人共同选择措施:限制暴露的函数、撤销意外授权、暂停受影响功能,或修正策略。如果高权限凭据已经暴露,除了消除暴露原因,还要按服务提供方的轮换流程停用旧凭据。公开的 publishable key 则按其预期用途处理。
修复后返回空结果,不能证明此前一直安全。保留的证据要区分发现问题、限制访问生效,以及部署环境复测通过的时间。负责事件处理的团队才能依据实际情况评估通知等义务。
什么条件下可以关闭这项权限问题?
只有在已部署范围内,约定的允许与拒绝用例都符合预期、正常业务仍可运行,且证据能对应到所测改动和调用者,才关闭这项权限问题。如果只有 RLS 已开启的配置、管理员查询成功或扫描全绿,却没有应用层复测,我们会继续保留问题。
| 记录项 | 需要保存的内容 |
|---|---|
| 预期访问边界 | A 可以读取和编辑自己私有记录中获准的字段;B 与未登录调用者不能。 |
| 所测改动 | 部署版本、数据库迁移,以及相关函数或策略定义 |
| 实际行为 | A/B/anon 的实际响应、返回字段、受影响行,以及写入被拒后数据未变的结果 |
| 剩余范围 | 未测路径、身份类型、部署差异和后续负责人 |
| 关闭决定 | 审查人、测试日期及关闭的具体问题,不作整个应用安全的结论 |
Cedars 评估案例介绍了我们在文档、QA 和范围明确的技术评估方面的工作。开工前先约定所需证据。我们的渗透测试服务可为正在运行的应用确定获授权的评估与复测范围。
完整的上线决策可参考软件发布 QA 检查清单。对这项权限问题,要在同一个部署版本上确认允许的请求成功、禁止的请求失败,保留两类结果后再关闭问题。
