千款 AI 应用审查暴露权限控制短板
作者称审查了 1,029 款 AI 构建应用和 188 款 ChatGPT 出现前的应用,发现前者严重漏洞比例为 40%,后者为 45%。样本中 AI 应用泄露密钥较少,但越权读写、登录校验和支付漏洞更突出。
AI 深度解读
AI 生成的应用更不安全吗?作者检查了 1,029 个由 Lovable、Bolt、v0、Cursor、Claude Code 等工具构建的公开应用,又拿 188 个 ChatGPT 出现前的同类应用作比较。结论并非 AI 全面更差,而是漏洞集中到了不同位置:权限、支付,以及浏览器直连数据库时的访问规则。
这对前端开发者很有用。页面能运行、按钮会隐藏、用户能登录,都不足以证明数据安全。真正要检查的是:绕过界面直接发请求,一个用户究竟能动到谁的数据。
40% 有严重问题,但不能只看这个数字
作者报告,40% 的 AI 应用至少存在一个高危或严重安全问题;作为对照,ChatGPT 出现前的应用比例是 45%。因此,这组数据不支持「AI 应用整体更不安全」的简单结论。
差异在漏洞类型。作者认为,AI 工具已经较少直接硬编码密钥,却仍经常弄错「谁能操作什么」。不过,15% 的应用仍把 .env 文件提交进仓库,常见原因是在创建 .gitignore 前就推送了项目。没有把密钥写进业务代码,不代表密钥没泄露。
这些数字来自 Redproof 对公开 GitHub 仓库的自动检查,时间是 2026 年 11 月。它们应当视作估计:静态分析只能读代码,看不到开发者直接在 Supabase 控制台修改的规则,部分发现还需要人工确认。
作者也是 Redproof 的开发者。这个利益关系需要交代,但也不能据此否定检查结果。更关键的问题是,原文没有充分展示样本如何匹配、不同项目复杂度如何控制,也没有展开被排除的那项噪声检查。
数据库开启了 RLS,为什么还会越权
Lovable、Bolt 和 v0 应用中,62% 被发现存在高危或严重问题;带有中间服务端的全栈 Cursor、Claude Code 项目,这一比例是 20%。
作者把风险指向浏览器直连 Supabase 或 Firebase 的结构。在这种结构下,数据库规则直接承担访问控制责任。规则放宽一点,攻击者就可能绕过页面,直接读取或修改数据。
开启安全机制,只是检查的起点,具体规则才决定它保护了谁。
原文中,只有 1% 的表没有开启行级安全(RLS),平台如今通常默认开启它。漏洞转移到了更细的地方:策略允许所有已登录用户读取所有行,数据库函数允许任何人调用,以及 Supabase Edge Functions 跳过登录检查。最后一种问题出现在全部应用的 5% 中。
「已登录」只是身份状态,不等于拥有某条记录。订单属于用户 A,用户 B 即使登录成功,也不该因此获得修改权限。
服务端同样需要做授权检查。62% 与 20% 是两组样本的观察结果,不能直接解释成「加一层 Node 服务就能解决安全问题」。
支付和 AI 接口,会把权限错误变成账单
160 个接入支付的应用中,50% 存在严重问题,9% 在支付流程本身存在漏洞。这两个数字不能混用,前者不代表一半应用都能伪造付款。
支付流程的典型错误有三类:
- Webhook 没有验证支付服务商的签名,就把订单标成已支付,攻击者可以伪造通知。
- 浏览器能够写入付费状态、积分或套餐,用户可以自行升级。
- 支付密钥被放进会发送到浏览器的变量中。
另一类风险来自代用户调用服务。441 个应用会自行调用 AI 模型;原文报告,6% 存在任何人都能使用的 AI 或邮件功能,费用由应用所有者承担。原文没有进一步解释这项比例的统计口径。
前端环境变量尤其容易造成误解。VITE_ 和 NEXT_PUBLIC_ 变量中的内容是公开的,不能存放 Stripe secret keys、service-role keys 或 AI API keys。这些密钥必须留在服务端,但接口是否允许陌生人调用,仍要另行检查。
我的判断
这份调查最有价值的部分,是把审查重点从「有没有登录页面」推到了真实请求上的权限验证。对直接使用 Supabase、Firebase 的项目,这比只检查页面交互更接近风险发生的位置。
但我不会据此给工具排安全榜。公开仓库、自动扫描、未展示的样本匹配方法,都限制了结论的解释范围。不同工具对应的项目类型、开发者经验和上线阶段,也可能影响结果。
浏览器直连数据库可以成立,前提是规则足够严格;服务端中转也可以失败,只要它遗漏对象归属检查。原文没有提供同一应用采用两种架构的对照数据,因此架构差异更适合作为排查线索,不能当作因果证明。
能拿来做什么
- 给自己的应用做一次双账号测试:A 创建私有记录,B 按记录 ID 尝试读取、更新、删除,再退出登录重复操作。测试实际 API 或 Supabase 请求,不能只看按钮是否隐藏。
- 逐张表、逐个数据库函数检查
anon key能做什么,以及任意已登录用户能做什么。私有数据应限制在各自所属的行,并运行 Supabase 的 Security Advisor,入口是Database → Advisors。 - 检查前端的
VITE_、NEXT_PUBLIC_变量及仓库中的.env,确认支付、数据库高权限和 AI 密钥没有进入公开代码或浏览器。 - 检查 Stripe Webhook 是否先验签再修改支付状态,并确认浏览器无法自行修改套餐、积分和付费标记;接入 AI 或邮件功能时,也要实际测试未登录请求。