Vercel 被黑了:一条 OAuth 信任链如何击穿整个平台

2026年4月19日,Vercel 发布了一则安全公告。内容不长,但信息量极大:

攻击者通过 compromise 了一个第三方 AI 工具(Context.ai)的 OAuth 应用,拿到了一名 Vercel 员工的 Google Workspace 账号,进而访问了 Vercel 内部系统和客户的环境变量。

如果你在用 Vercel,你应该关心这件事。但真正该关心的不是"Vercel 不安全"——这件事跟 Vercel 本身的安全能力关系不大。它是一个关于我们所有人每天都在参与的 OAuth 信任模型,到底有多脆弱的故事。

我用了几天的时间追踪了 Vercel 官方公告、Context.ai 的安全更新、Trend Micro 的技术分析,以及 HN 和 dev.to 上的讨论。这篇文章把我看到的东西整理出来——攻击链还原、风险面分析、你应该做什么,以及这件事对我们所有人的启示。


攻击链还原:从 Roblox 外挂到 Vercel 内网

整条攻击链可以分为四个阶段。每一步都是"合法"操作——攻击者没有利用 0-day,没有绕过防火墙,没有暴力破解密码。他们只是顺着 OAuth 信任关系一路走进去的。

第一阶段:Lumma Stealer 感染

2026 年 2 月,Context.ai 的一名员工下载了 Roblox 游戏外挂脚本。这个脚本携带了 Lumma Stealer 信息窃取木马。

Lumma Stealer 不是新东西。它专门从受害者的浏览器和系统中提取:

  • 保存的密码
  • 浏览器 cookie
  • 浏览器中存储的 OAuth token
  • 加密货币钱包信息
  • 双因素认证备份码

这名员工用工作设备下载了外挂。结果:他的 Google Workspace 凭证、session token、以及所有已授权的 OAuth token 被完整提取。

第二阶段:从 Context.ai 到 Google Workspace

攻击者拿到了 Context.ai 员工的 Google Workspace token 后,做了一件非常关键的事:他们用这个 token 访问了 Context.ai 自己的 Google Workspace OAuth 应用

这个 OAuth 应用是 Context.ai 为他们的消费者产品(AI Office Suite)开发的。它被 Vercel 的员工授权过——也就是说,有 Vercel 员工用他们的 Google Workspace 账号登录过 Context.ai 的服务,并且授权了所有请求的权限

注意这里的第一层信任传递:

Context.ai 员工授权了 Context.ai 的 OAuth 应用
    ↓
Vercel 员工也授权了同一个 OAuth 应用
    ↓
攻击者拿到了 Context.ai 的控制权
    ↓
因此攻击者可以访问所有授权过这个应用的 Google 账号

第三阶段:OAuth token 的横向移动

2026 年 3 月,攻击者使用被盗的 OAuth token 进入了 Vercel 员工的 Google Workspace 账号。

这一步绕过了多因素认证(MFA)。因为 OAuth token 本身就是一个已经通过认证的凭据——当你授权一个应用时,Google 发给它一个长期有效的 token。攻击者不需要密码,不需要过 MFA,直接用 token 登录就行。

从 Google Workspace 账号,攻击者做了横向移动,进入了 Vercel 的内部系统:

  • 内部管理工具
  • Issue tracker
  • 内部环境配置

第四阶段:环境变量暴露

进入 Vercel 内部系统后,攻击者开始枚举客户的环境变量。

关键点来了:Vercel 有两种环境变量存储模式

  • 标记为 "Sensitive" 的环境变量:加密存储,不可读取
  • 未标记为 "Sensitive" 的环境变量:以明文形式存储,内部人员可读取

攻击者访问的是未标记为 Sensitive 的变量。这些变量包括 API key、数据库连接字符串、第三方服务 token——本质上就是你的整个应用的后端凭证。

Vercel 官方确认:"Sensitive" 环境变量没有证据表明被访问。但未标记的变量,对攻击者来说是明文可读的。

攻击链总结

Roblox 外挂脚本
  → Lumma Stealer 木马
    → Context.ai 员工 Google 凭证泄露
      → Context.ai OAuth 应用被盗用
        → Vercel 员工 Google Workspace 被入侵(绕过 MFA)
          → Vercel 内部系统被访问
            → 客户环境变量(明文)被暴露

整个过程,没有一次攻击是"非法"的——攻击者每一步都在使用合法的身份认证机制。


这件事为什么重要

1. OAuth 信任模型的系统性脆弱

OAuth 2.0 的设计假设是:如果你授权了一个应用,你信任这个应用不会滥用你的权限

但这条信任链有一个致命问题:

你信任的不是应用本身,而是应用的开发者、基础设施、员工设备安全、安全事件响应能力……以及这个应用的所有其他用户。

Vercel 不是 Context.ai 的客户。Vercel 和 Context.ai 之间没有任何商业关系。但因为有一个 Vercel 员工用 Google Workspace 账号授权了 Context.ai 的应用,Vercel 就间接地把信任传递给了 Context.ai。

这跟供应链攻击的逻辑一模一样:你信任你的供应商,供应商信任他的供应商,最底层的一环被攻破,所有人一起完蛋。

2. MFA 在 OAuth 面前是纸老虎

多因素认证是过去十年企业安全最重要的进步。但 OAuth token 完美地绕过了它。

一旦你授权了一个 OAuth 应用,Google(或者任何 OAuth provider)发给那个应用一个长期有效的 token。这个 token 不需要密码,不需要 MFA,不需要二次验证。它就是一个"我已经认证过了"的通行证。

攻击者拿到这个 token,就等于拿到了你的账号。MFA 保护的是密码登录路径,但 OAuth token 走的是另一条路。

这在安全领域叫 "token 盗窃"(Token Theft),是 2025-2026 年最常见的企业入侵向量。微软、Google、Okta 都在各自的报告中提到了这一点。

3. 平台即服务(PaaS)的安全边界

Vercel 的环境变量模型暴露了一个更深层的问题:PaaS 平台的安全边界在哪里?

你把应用部署在 Vercel 上,你把 API key 存在 Vercel 的环境变量里。你相信 Vercel 能保护这些凭证。但 Vercel 的安全取决于:

  • Vercel 员工有没有授权可疑的第三方应用
  • Vercel 内部系统的访问控制
  • Vercel 的环境变量加密策略
  • Vercel 的供应商(Google Workspace)有没有被间接攻击

你无法控制其中任何一条。你只能控制一件事:你存在 Vercel 里的凭证是不是标记为了 Sensitive


如果你在用 Vercel,现在该做什么

Vercel 已经发布了详细的安全指南。我把它总结成一个你可以今天就去做的行动清单,按优先级排序。

第一优先级:检查环境变量

登录 Vercel Dashboard,进入每个项目的环境变量页面。检查:

  1. 哪些变量没有标记为 "Sensitive"?
  2. 这些变量里有没有包含真实的凭证?(API key、数据库 URL、token……)

如果有,把这些变量视为已暴露。

第二优先级:轮换(Rotate)凭证

轮换一个凭证的意思是:

  1. 去颁发这个凭证的服务那里(AWS、OpenAI、Supabase、Stripe……)生成一个新的 key
  2. 用新的 key 更新 Vercel 的环境变量
  3. 把变量标记为 "Sensitive"
  4. 重新部署项目
  5. 回到原来的服务那里撤销旧的 key

注意顺序:先创建新的,更新,部署成功之后,再撤销旧的。直接删除 Vercel 里的变量没用——旧凭证在服务端仍然是有效的。

第三优先级:按影响范围排序轮换

如果你的凭证很多,不要随机轮换。按影响范围排序:

优先级 类型 例子
Tier 1(最高) 云厂商 key、数据库凭证、支付 key AWS access key、Supabase service role key、Stripe secret key
Tier 2(高) 第三方 SaaS API key OpenAI key、Anthropic key、SendGrid key、Resend key
Tier 3(中) 分析工具、Webhook secret GA4、Plausible、webhook 签名 key

Tier 1 的凭证必须在今天就轮换。Tier 2 在 24 小时内。Tier 3 在本周内。

其他应该做的事

  • 开启 2FA:Vercel 支持 authenticator app 和 passkey
  • 检查活动日志:Vercel Dashboard 的 Activity Log 里有所有操作记录
  • 检查近期部署:看看有没有异常部署
  • 检查 Deployment Protection 设置:确保至少设为 Standard
  • 轮换 Deployment Protection bypass token(如果有的话)

Vercel 还做了两个产品层面的改进:

  1. 新建环境变量默认标记为 Sensitive
  2. 提供了跨项目的环境变量管理页面,方便快速审计

这件事的更大教训

教训一:最小化 OAuth 授权

每次你点"Allow"授权一个应用的时候,想一下:

  • 这个应用真的需要它请求的所有权限吗?
  • 我可以用一个工作邮箱/Google Workspace 的非主账号来授权吗?
  • 这个应用的开发者是谁?他们的安全能力如何?

Vercel CEO Guillermo Rauch 在公告中说,那名员工授权了 Context.ai 请求的所有权限。这在 OAuth 授权页面非常常见——你会看到一个长长的权限列表,然后习惯性地点 Allow。但每一个权限都是一条潜在的入侵路径。

教训二:把所有环境变量都当成 Sensitive

在 Vercel(或任何平台)上,所有包含凭证的环境变量都应该标记为 Sensitive。没有例外。

"非敏感"的环境变量——比如应用名称、功能开关——这些可以不标记。但只要变量里包含任何可以被用来访问其他系统的字符串,它就是敏感变量。

Vercel 已经把新建环境变量的默认值改成了 Sensitive。但历史变量不会自动变,需要你手动检查。

教训三:假设 OAuth token 会被偷

OAuth token 的设计是"长期有效"。这意味着一旦被盗,攻击者可以无限期使用,直到 token 过期或者你主动撤销。

Google Workspace 默认的 OAuth audit log 保留期是6 个月。如果攻击者的停留时间超过 6 个月,日志可能已经不在了。

定期审查你授权的 OAuth 应用,撤销不再使用的那些。这不是"安全团队才做的事",这是每个用了第三方 SaaS 工具的开发者的基本操作。

教训四:平台的安全 ≠ 你的安全

Vercel 是一个好平台。但任何平台的安全性都受限于它的最弱环节——可能是一个员工的设备、一个供应商的安全事件、一个 OAuth 应用的配置。

你不能假设平台会替你保护一切。你能做的是:

  • 控制你自己的凭证(轮换、加密、最小权限)
  • 监控你自己的系统(活动日志、部署审计)
  • 减少对平台的信任假设(敏感数据加密存储、密钥轮换策略)

时间线回顾

时间 事件 确认状态
~2026 年 2 月 Context.ai 员工感染 Lumma Stealer 已确认(Hudson Rock, CyberScoop)
~2026 年 3 月 攻击者进入 Context.ai AWS,提取 OAuth token 已确认(Context.ai 公告)
2026 年 3 月 攻击者用 OAuth token 进入 Vercel 员工 Google Workspace 已确认(Vercel 公告)
2026 年 3-4 月 攻击者横向移动到 Vercel 内部系统 已确认
2026 年 4 月 10 日 OpenAI 通知某 Vercel 客户 API key 泄露 单源报道
2026 年 4 月 19 日 Vercel 发布安全公告 已确认

注意这个时间线的一个关键修正:最初 Trend Micro 的分析推测入侵时间可能长达 22 个月,但 Context.ai 的安全公告澄清,实际从初始感染到发现只有约 2 个月。这说明 Context.ai 自己的检测能力在事后有所提升,但也暴露了一个问题——入侵可能已经发生了两个月才被发现


一句话总结

Vercel 这件事不是关于"Vercel 不安全"。它是关于我们所有人每天点的那个 "Allow" 按钮——每一次 OAuth 授权,你都在把自己的安全交给别人。

今天花 30 分钟检查你的 Vercel 环境变量,轮换那些没标记 Sensitive 的凭证。然后,想想你授权过的所有第三方应用——哪些是真的需要的,哪些是习惯性点的 Allow。


参考来源