在 Web 应用中使用 Firebase 作为后端服务时,开发者通常会在客户端代码中嵌入 Firebase 配置文件,其中包含一个 API Key。这个 Key 在大多数场景下是安全的,因为 Firebase 服务本身通过 Security Rules 和 App Check 来控制访问权限。然而,当这个 Key 被意外用于调用非 Firebase 的付费 Google Cloud API(如 Gemini API)时,攻击者可以利用无限制的 Key 在短时间内产生巨额账单。本文从一起典型的 13 小时产生约 €54,000 账单突增的事件出发,剖析工程根因并给出可操作的防护参数。
工程根因:无限制浏览器 API Key 的开放权限
Firebase 为 Web 应用自动创建一个「Browser key」,默认情况下这个 Key 的 API 限制(API Restrictions)是开放的,即可以调用项目中已启用的所有 Google Cloud API。在 2024 年 5 月之前创建的 Firebase 项目,如果未手动添加 API 限制,攻击者获取到这个 Key 后即可调用 Generative Language API(Gemini API),而无需通过 Firebase 的任何安全机制验证。只要项目中启用了 Gemini API,这个无限制的 Browser key 就会成为攻击入口。
关键的技术细节在于:Firebase API Key 的设计目的是「标识项目」而非「控制访问」。即使在 Firebase 官方文档中也明确指出,API Key 可以安全地嵌入客户端代码,但这仅适用于纯 Firebase 服务。一旦项目启用了其他付费 API(如 Gemini),如果没有对 Key 进行 API 级别限制,攻击者可以直接使用该 Key 向 Gemini API 发起请求,所有费用会记入项目绑定的结算账户。
从攻击链路来看,攻击者通常通过以下步骤实现账单突增:首先在公开代码仓库、配置泄漏文件或网络流量中获取 Firebase 配置对象中的 apiKey;然后检查项目是否启用了 Gemini API(可通过 API Explorer 或直接调用尝试);最后编写脚本在短时间内发起大量高并发请求,使用昂贵的 Gemini Pro 或 Gemini Ultra 模型,每次调用都会产生对应的 token 费用。根据实际案例统计,一个中等规模的攻击可以在 10 到 15 小时内产生超过 5 万欧元的费用。
第一层防护:API 限制与应用程序限制
最直接的防护手段是限制 API Key 只能访问特定的 API。对于 Firebase Browser key,开发者应在 Google Cloud Console 的「API 和服务」→「凭据」页面找到对应的 Browser key,点击编辑后在「API 限制」选项中选择「限制密钥」,仅保留必要的 Firebase 相关 API。具体需要保留的 API 包括:Firebase Management API、Firebase Installations API、Identity Toolkit API、Cloud Firestore API(如果使用)等。关键的是,不要将 Generative Language API 加入允许列表,这样即使 Key 泄漏,攻击者也无法调用 Gemini API。
应用程序限制(Application Restrictions)是更细粒度的防护措施。对于 Browser key,建议添加 HTTP 来源限制(HTTP referrers),只允许来自你自己域名的请求。例如,如果你的应用托管在 example.com,应将限制设置为 https://example.com/* 和 https://example.firebaseapp.com/*。这样即使攻击者获取了 Key,也无法从其他域名发起请求。需要注意的是,这种限制对移动端或桌面端应用无效,因为它们的请求不携带 HTTP referrer。
对于必须使用 Gemini API 的场景,正确的做法是创建独立的 API Key,专门用于 Gemini 调用,并在「API 限制」中只允许 Generative Language API。然后将这个独立的 Key 存放在后端服务(如 Firebase Cloud Functions)中,客户端不直接持有该 Key。
第二层防护:配额限制与预算警报
即使攻击者通过某种手段绕过了 API 限制,配额(Quota)限制可以有效遏制损失。在 Google Cloud Console 中,为每个 API Key 设置每分钟请求次数(QPS)和每日调用上限。对于 Gemini API,建议将每分钟请求数设置为业务峰值的 1.5 到 2 倍,例如正常业务每分钟 100 次调用,则将配额设置为 150 到 200 次。当配额被突破时,API 会返回 429 Too Many Requests 错误,攻击者无法继续消耗资源。
更重要的防护手段是预算警报(Budget Alerts)。在 Google Cloud Billing 的「预算和提醒」中创建预算,设置阈值触发警报。建议配置三级阈值:50% 预算使用时发送邮件通知,80% 时发送短信或 Slack 消息,100% 时自动关闭相关 API 或暂停项目。具体的预算金额应根据业务预期设定,对于初创项目,建议初始预算设置为月均费用的 3 倍,随后根据实际使用情况调整。
此外,Google Cloud 还支持「结算预算提醒」功能,当月度费用超过设定值时自动发送通知。结合 Cloud Monitoring 的提醒策略,可以实现当 API 调用量异常增长时(比如单小时调用量超过平均值的 5 倍)自动触发告警。
第三层防护:后端代理与 App Check
最安全的架构是将所有付费 API 调用放在后端,客户端通过 Firebase Cloud Functions 或自建后端服务间接调用。具体实现为:客户端发送请求到 Firebase Function,Function 使用服务账号(Service Account)或应用默认凭证(ADC)调用 Gemini API,返回结果给客户端。这样即使客户端被攻击,攻击者也无法直接获取用于支付的凭证。
Firebase App Check 是另一层防护,它通过验证请求来自真实的客户端应用而非脚本或爬虫来防止滥用。对于 Web 应用,App Check 可以与 reCAPTCHA v3 集成,验证请求来自合法的浏览器环境。虽然 App Check 不能直接防止 API Key 泄漏,但可以大幅提高攻击者的成本,使自动化脚本难以大规模发起请求。
在实际部署中,建议采用以下参数配置:App Check 的强制实施阈值设置为 0.9,即只有评分高于 0.9 的请求才被接受;对于高风险操作(如批量生成内容),在 Cloud Function 中添加额外的业务逻辑校验,如请求频率限制、IP 黑白名单等。
监控与响应:异常检测清单
建立完善的监控体系是快速发现和响应攻击的关键。以下是推荐的关键监控指标和阈值:
在 API 调用监控方面,应在 Cloud Monitoring 中创建以下指标:Gemini API 的请求计数(每秒请求数)、Token 消耗量(输入 token 加输出 token)、错误率(特别是 429 和 403 错误)。异常阈值建议设为:请求量超过历史平均值的 3 倍时触发一级告警,超过 5 倍时触发二级告警并自动暂停相关 API Key。
在结算监控方面,启用 Cloud Billing 的每日预算报告,设置当费用超过 €1,000 时发送即时通知。对于高风险项目,可以开启「自动预算行动」,当费用超过设定阈值时自动关闭 API 或将项目置于只读模式。
响应流程应包括以下步骤:第一步,立即在 Google Cloud Console 中撤销可疑的 API Key 并重新生成;第二步,关闭项目级别的 Gemini API(如果暂时不需要);第三步,检查 Cloud Logging 中的 API 调用日志,提取攻击者的 IP 地址、请求模式等信息;第四步,联系 Google Cloud 支持团队,说明情况并申请账单调整(如果符合条件)。
总结
Firebase 浏览器端 API Key 的安全性取决于开发者是否正确配置了 API 限制和应用程序限制。无限制的 Key 可以成为攻击入口,导致 Gemini API 等付费服务在短时间内产生巨额账单。防护的核心在于:限制 API Key 的访问范围、设置合理的配额上限、启用预算警报、并通过后端代理架构避免在客户端暴露付费 API 的调用能力。结合 App Check 和完善的监控告警体系,可以在攻击早期阶段发现异常并快速响应,将损失降到最低。
资料来源:本文部分技术细节参考了 Google Firebase 官方文档关于 API Key 管理的最佳实践,以及 Tech Newsday 报道的类似 API Key 泄漏导致高额账单的安全事件。