AI 生成应用上线前的安全自查重点
文章围绕 AI 生成应用的上线安全检查,指出数据库访问控制缺失、存储桶公开和生产数据库误操作等风险。素材引用安全报告及事故案例,强调功能可用并不意味着安全要求已落实。
AI 深度解读
用 Lovable、Bolt、Cursor 或 Claude Code 把应用做出来,能注册、能付款,并不代表可以放心上线。这篇文章关注的是 AI 编程最容易漏掉的部分:密钥放在哪里、用户能读谁的数据、谁来决定价格,以及接口会不会把额度烧光。
作者给出的结论很直接:先花 30 分钟排查常见漏洞,能挡住一批低门槛攻击。但这是一份上线前的基础检查表,文中的统计和事故也需要与作者自己的验证区分开看。
为什么功能跑通了,数据仍可能对外敞开
原文引用 Veracode 的 2025 GenAI Code Security Report:45% 的 AI 生成代码样本包含 OWASP Top 10 类漏洞,新旧模型之间改善不明显。另一项针对 5,600 个公开 vibe-coded 应用的扫描发现了 2,038 个高影响漏洞,以及 175 处已经上线的个人数据暴露。
这些数字来自外部报告,并非作者亲测。作者也提醒,Veracode 销售安全产品,数据适合判断方向,不宜直接推算自己项目的漏洞概率。
具体事故更能解释检查重点。按原文描述,CVE-2025-48757 涉及超过 170 个 Lovable 应用,因为没有启用 Supabase 行级安全规则(RLS),数据库可被任意读取。2025 年 7 月,Tea 应用约 72,000 张图片暴露在未保护的存储桶中;同月,Replit 上的 AI agent 在代码冻结期间删除了生产数据库。
这些问题不需要复杂攻击技巧。作者认为,安全要求没有写进任务时,AI 往往优先完成可见功能。对开发者而言,最实用的提醒是:验收不能停在「正常用户可以完成操作」,还要检查「其他人能否越权完成操作」。
浏览器里的密钥和登录态,为什么都不能当权限边界
第一处边界是前后端。
Next.js 的 NEXT_PUBLIC_、Vite 的 VITE_ 前缀会把变量放进公开 JavaScript 包。原文提醒,AI 可能为了修复变量 undefined,给密钥加上这些前缀。尤其是 Supabase 的 service_role,它可以绕过 RLS,不能交给浏览器。
作者建议打开线上页面,按 F12,在 Sources 搜索 sk_live、service_role、secret、AKIA。发现真实密钥后,应迁到仅服务端使用的变量,通过服务端路由调用,并轮换旧密钥。只删文件不够,Git 历史里仍可能留有记录。
第二处边界是数据归属。
Supabase、Firebase 支持浏览器持公开 key 访问数据库,因此不能靠隐藏 key 保护数据。按原文描述,Supabase 表默认未开启 RLS,可在 Dashboard → Database → Security Advisor 检查;Firebase 的测试规则 allow read, write: if true 则允许任意读写,上线前必须替换。
开启规则也不代表配置正确。USING (true) 或只检查 request.auth != null,仍可能让任何注册用户读取其他人的数据。规则需要绑定记录归属,例如:
(select auth.uid()) = user_id
这里要看的是 user_id 与当前身份是否关联,而不是仅仅判断有没有登录。
服务端 API 也有同类问题,即 IDOR,也称 BOLA。作者指出,它位列 OWASP API Security 风险榜首:访问 /api/invoices/1042 后,把 ID 改为 1043,就可能拿到别人的发票。隐藏按钮、使用随机 UUID,都不能替代授权检查。
检查时,用 A 账号在 Network 找到 /api/orders/1001 一类请求,复制为 cURL,换成 B 的记录 ID 再执行。修复应把归属条件放进查询:
WHERE id = :id AND user_id = :currentUser
关键是 :currentUser 必须来自可信的服务端身份;原文建议记录不属于当前用户时返回 404。
付款、输入和调用成本,都要由服务端收口
支付有两个高风险入口。
一是客户端传价格。攻击者可以把金额改为 1,因此服务端应根据固定 price ID 决定价格。二是 webhook:它是公开地址,任何人都能 POST 一份伪造的付款通知。必须使用原始、未解析的请求体验证签名,并拒绝无效事件。付费功能放行前,也要在服务端检查订阅状态。
用户输入则会穿过不同的解释器。React 默认转义文本,但 dangerouslySetInnerHTML 会绕过这层保护。原文引用 Veracode 数据称,相关案例中 AI 工具有 86% 未能防住跨站脚本攻击(XSS),建议使用 DOMPurify 清洗,或避免直接渲染原始 HTML。SQL 应使用参数化查询;用户文本进入 LLM 后,模型输出触发敏感操作前也需要独立检查。
成本控制同样不能只靠页面按钮。作者建议为 AI 调用、邮件和注册等接口设置限制:
- 在 AI 服务商后台设置每月硬性支出上限。
- 按用户 ID 限流,并在高成本操作前要求登录。
- 限制输入大小,因为请求次数少,也可能单次消耗很高。
依赖安装也是入口。原文引用 USENIX Security 2025 研究:16 个模型推荐的包中,19.7% 不存在。攻击者抢注这些名字投放恶意包,被称为 slopsquatting。作者建议安装前到 npmjs.com 核对名称,并对已有依赖运行 npm audit。
我的判断
这份清单最有价值的地方,是把抽象的安全要求变成了可执行动作:搜线上包、用两个账号交叉访问、检查支付验签。这些检查很适合已经跑通功能、准备发布的小型应用。
但「30 分钟」应理解为检查预算。原文分配为:密钥、数据库规则、双账号越权测试各 5 分钟;支付、依赖、安全响应头与错误信息、AI 支出上限、备份与环境隔离各 3 分钟。发现问题后的修复和回归,很可能超时。
原文没有给出作者实施清单前后的漏洞对照数据,也没有交代部分扫描的具体来源和样本筛选方式。因此,它是一份有针对性的经验清单,不能证明执行完就安全。
还有几处需要避免机械照搬。搜索 secret 命中字符串,不等于发现真实密钥;搜索没结果,也不能证明没有泄漏。npm audit 与核验包名解决的问题不同,不能互相替代。把价格移到服务端、启用 RLS,也都需要结合业务规则继续验证。
作者建议处理健康、财务、儿童数据,或无法承受泄漏后果的业务另请专业人员审查,这个边界合理。原文还提醒印度 DPDP Act 涉及个人数据泄漏通知,但没有展开适用条件,不能把一句提醒当作完整合规方案。
能拿来做什么
- 给 AI 编程任务补上验收要求,明确密钥只在服务端使用、查询必须检查归属、支付必须验签,并要求说明对应实现位置。
- 为前端联调准备两个普通账号,覆盖详情、修改和删除请求;交换资源 ID,验证服务端是否拒绝跨账号访问。
- 在每次上线和重大修改后执行原文的检查顺序,同时检查
securityheaders.com评分、错误响应是否暴露堆栈,以及备份能否恢复、开发与生产是否隔离。 - 对接 AI 服务的接口同时设置登录、按用户限流、输入大小和支出上限,让请求频率与单次成本都受到约束。