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,进入每个项目的环境变量页面。检查:
- 哪些变量没有标记为 "Sensitive"?
- 这些变量里有没有包含真实的凭证?(API key、数据库 URL、token……)
如果有,把这些变量视为已暴露。
第二优先级:轮换(Rotate)凭证
轮换一个凭证的意思是:
- 去颁发这个凭证的服务那里(AWS、OpenAI、Supabase、Stripe……)生成一个新的 key
- 用新的 key 更新 Vercel 的环境变量
- 把变量标记为 "Sensitive"
- 重新部署项目
- 回到原来的服务那里撤销旧的 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 还做了两个产品层面的改进:
- 新建环境变量默认标记为 Sensitive
- 提供了跨项目的环境变量管理页面,方便快速审计
这件事的更大教训
教训一:最小化 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。