当你在 GCP 控制台点击 "删除" 按钮时,你理所当然地认为这个 API 密钥会立即失效,再也无法被任何人使用。但事实并非如此。

Google API 密钥的删除操作遵循最终一致性原则,更新会逐渐传播到全球各地的服务器,而不是同时生效。这意味着在你删除密钥后的一段时间内,部分服务器仍然会接受这个已经被标记为删除的密钥。攻击者如果持有泄露的密钥,在这段时间内可以继续访问你的数据和已启用的 API 服务,包括 Gemini。

更严重的是,GCP 控制台不会显示这个已经被删除的密钥,也不会告诉你它仍然在工作。你只能被动等待 Google 的基础设施完成更新,没有任何方法可以加速这个过程,也无法确认密钥何时真正停止工作。

撤销窗口指的是从你删除密钥的那一刻起,到最后一次成功通过该密钥进行身份验证的时间间隔。

如果这个窗口只有几微秒,那么用户几乎不会察觉到任何差异,行为也符合预期。但如果窗口长达几分钟甚至几十分钟,每多一秒都在给攻击者更多时间滥用被盗的密钥。

为了准确测量 Google API 密钥的撤销窗口长度,研究人员在两天内进行了 10 次独立测试。每次测试研究人员都会创建一个新的 API 密钥,立即删除它,然后以每秒 3 到 5 次的频率发送身份验证请求,直到连续几分钟没有任何有效响应为止。

研究人员选择这个请求速率是为了尽可能多地遍历 Google 全球不同的身份验证服务器,同时避免对其基础设施造成不必要的负担。需要注意的是,攻击者不会像研究人员这样限制请求速率,因此研究人员测量的数值可能并不代表最坏情况。

在所有 10 次测试中,最长的撤销窗口接近 23 分钟。这是一个令人震惊的时长,对于一个已经被删除的凭证来说,它仍然可以成功进行身份验证。

最短的窗口也有将近 8 分钟,中位数约为 16 分钟。不同测试之间的成功率差异极大,删除后一分钟,有的测试中 79% 的请求仍然成功,而有的测试中只有 5% 的请求成功。

攻击者持有被盗密钥时,不会看到一个清晰的截止时间,也不会有可预测的衰减模式。访问权限会断断续续地工作,直到某一刻突然完全停止。

为了更直观地展示 Google 基础设施的不一致性,研究人员使用 GCP 中的 "按凭证流量" 图表监控了其中一次测试。蓝色的下线代表成功的身份验证请求,它清晰地反映了撤销窗口的长度。

但研究人员意外地发现了第二条线。绿色的上线代表被拒绝的请求,标签显示为apikey:UNKNOWN。研究人员原本以为无效请求会被直接丢弃,不会与任何项目关联。但实际上,GCP 会将这些请求包含在项目的流量图表中。

为了进一步了解这个神秘的apikey:UNKNOWN值,研究人员尝试使用几天前已经删除的 API 密钥进行身份验证。令人惊讶的是,这些请求也出现在同一个图表中,并被归入同一个apikey:UNKNOWN类别。

研究人员的最佳猜测是,Google 会在密钥删除后保留项目归属信息,以防用户决定恢复该凭证。

这对于正在调查凭证泄露事件的事件响应团队来说可能会造成混淆。任何使用已删除 Google API 密钥发出的请求都会被归入同一个 UNKNOWN 类别,很难区分哪些请求与特定的泄露凭证相关。这个桶中的请求可能意味着威胁者仍在尝试使用已删除的密钥进行身份验证,也可能只是某个不相关的合法服务仍在使用过时的密钥。

如果你处于 23 分钟的撤销窗口内,应该重点关注使用泄露密钥进行的有效身份验证。如果你已经超出了这个窗口,那么风险看起来非常低。

研究人员最初的实验是从美国东海岸的住宅 IP 地址进行的。研究人员假设在不同 GCP 区域的虚拟机上运行类似的实验可能会发现更多的不一致性。

研究人员在三个区域启动了虚拟机,分别是us-east1europe-west1asia-southeast1。然后进行了 5 次测试,每次测试删除一个 API 密钥,并从三个虚拟机并行发送请求。

有两个发现特别值得注意。首先,在密钥被删除后立即,不同区域的虚拟机看到的身份验证成功率差异非常大。

在第一次测试中,us-east1区域的成功率为 82%,europe-west1为 60%,而asia-southeast1仅为 32%。距离美国更远的虚拟机反而更快地检测到密钥已被删除,这与研究人员的预期相反。研究人员无法从外部确切知道原因。Google 的请求路由比 "虚拟机区域等于服务器区域" 要复杂得多,新加坡的虚拟机不一定在与新加坡的服务器通信。但这种模式在所有测试中都保持一致,表明区域基础设施、缓存或路由亲和性的某些方面正在驱动这种差异。

其次,这种区域差异不仅仅存在于第一分钟。在整个撤销窗口期间,asia-southeast1的中位请求身份验证成功率为 22%,而us-east1europe-west1都在 49% 左右。亚洲区域的成功率每分钟都保持较低水平,而不仅仅是在开始时。

无论是什么原因导致了这些差异,服务器的位置显然会影响已删除密钥在删除后的行为。

研究人员所有的测试都使用了具有 Gemini 访问权限的密钥,但研究人员观察到,限定于其他 GCP API 的密钥也表现出相同的行为,例如 BigQuery 和 Maps。这种延迟是凭证类型的属性,而不是项目上启用了哪些 API 的属性。

为了完整起见,研究人员还测试了另外两种 Google 凭证类型:

  • 新的 Gemini API 密钥(AQ. 前缀)。删除传播时间约为 1 分钟。

  • Google 服务账户密钥(Service Account keys)。删除传播时间约为 5 秒。

这两种凭证都运行在 Google 的全球规模基础设施上,但它们的撤销速度都比研究人员测量的 Google API 密钥的 23 分钟快得多。

研究人员向 Google 报告了这个问题。Google 将报告关闭为 "不予修复"。据研究人员了解,该团队的立场是,传播延迟是系统的已知属性,不是安全问题。

虽然 Google 公开记录了他们的 IAM API 是最终一致性的,但他们没有专门为 Google API 密钥记录这种行为。

Google 规模的分布式系统确实很难构建,这不是对 GCP IAM 团队的批评。但 23 分钟的撤销窗口从根本上与用户对删除按钮的期望相矛盾。这种期望与 Google 实际行为之间的差距凸显了四个问题:

第一,用户界面极具误导性。当你删除密钥时,Google 会将其从你的视图中移除,并告诉你 "一旦删除,它将不能再用于发出 API 请求"。这个陈述显然是错误的。用户无法知道密钥是否仍然有效,无法加速撤销过程,也无法确认它何时完全停止工作。

第二,Google 已经为其他凭证类型构建了更快的撤销机制。服务账户凭证的撤销传播时间约为 5 秒。Gemini 较新的 API 密钥格式传播时间约为 1 分钟。两者都运行在 Google 的规模上。两者都表明,对于 Google API 密钥来说,这在技术上也是可以解决的。

第三,长一致性窗口与身份验证的本质不兼容。删除凭证时的期望是该凭证立即失效。即使是几秒钟的延迟也很重要,正如 Eduard 去年对 AWS 的研究所显示的那样。

第四,长撤销窗口破坏了即时凭证生成(Just-in-Time credential minting)的理念。想要动态生成 Google API 密钥的服务提供商必须在撤销后预留 23 分钟的缓冲时间,才能保证密钥真正失效。这与 JIT 应该如何工作的理念完全不兼容。

在 Google 推出更快的撤销机制之前,弥补这个差距的责任落在了用户身上。有两件事可以帮助降低风险:

第一,将密钥删除视为一个 30 分钟的操作,而不是即时操作。如果你正在响应 Google API 密钥泄露事件,假设密钥在点击删除后的 30 分钟内仍然有效。这给了你一个超出研究人员观察到的最长 23 分钟的安全缓冲。围绕这个窗口计划你的事件响应的其余部分。

第二,密切监控窗口期间的使用情况。在 GCP 控制台的 "已启用的 API 和服务" 下,按凭证查看 API 请求。如果你在删除后看到来自该凭证的意外使用,那么可能有人正在积极利用它。

在需要凭证立即失效的安全场景下,使用长达 23 分钟的最终一致性窗口是不合适的。在 Google 改变这一点之前,请将每一次密钥删除都视为一个 30 分钟的操作,并在这段时间内密切监控是否有滥用行为。

参考:aikido的《Google API keys keep working after you delete them》

声明:本文来自黑鸟,版权归作者所有。文章内容仅代表作者独立观点,不代表安全内参立场,转载目的在于传递更多信息。如有侵权,请联系 anquanneican@163.com。