当 WebSocket 升级绕过 Lambda@Edge:你的安全防线为何失效?

原创
alex 2小时前 阅读数 1 #头条

当 WebSocket 升级绕过 Lambda@Edge:你的安全防线为何失效?

攻击如何绕过 Lambda@Edge

我们最近遭遇了一次攻击。攻击者把 HTTP/1.1 请求打扮成 WebSocket 升级,发到我们的 CloudFront 分发,这些请求绕过了 viewer-request Lambda@Edge 函数,直接抵达源站。我们的 bot 检测、认证、限流和地理封锁,全都在这个函数里,等于全部落空 来源:Prosopo。

我们的架构很典型。CloudFront 在最前面,接受 HTTP/1.1、HTTP/2 和 HTTP/3;Lambda@Edge viewer-request 函数承载全部安全逻辑;源站默认信任边缘函数已经审查过每个请求 来源:Prosopo。这套模型的隐含前提,是每个请求都会经过 viewer-request。AWS 文档也确实说 viewer-request 函数在 CloudFront 收到请求后、检查缓存前执行,只列了两个例外,自定义错误页和 HTTP 到 HTTPS 自动重定向 来源:Prosopo。读起来就像“每个请求都会经过我的函数”。

但边缘函数看不到 Upgrade 头,而 CloudFront 始终接受 HTTP/1.1 来源:Prosopo。于是攻击者发送的请求看起来再普通不过,GET /api/login,带 Connection: Upgrade、Upgrade: websocket、Sec-WebSocket-Key 和 Sec-WebSocket-Version 头 来源:Prosopo。这些请求到达了我们的源站,viewer-request 函数没有拦截,bot 检查根本没有机会去质询客户端。

量化数据与技术细节

这件事发生在 2026 年 11 月 17 日,作者 George Oastler 在 Prosopo 博客上记录了整个过程,一篇 9 分钟阅读的技术文章 来源:Prosopo。攻击的核心手法,是发送 HTTP/1.1 加 Upgrade 头。CloudFront 的 HTTP/1.1、HTTP/2、HTTP/3 兼容性本来是好事,在这个场景里反而成了漏洞面,因为边缘函数看不到 Upgrade,而 CloudFront 对 HTTP/1.1 来者不拒 来源:Prosopo。

作者给出了两条修复建议。第一条,在 AWS WAF 里阻止不需要 WebSocket 的路径上的升级请求 来源:Prosopo。这相当于在边缘层提前掐断,不让升级请求进入源站。第二条,让源站拒绝边缘函数未签名的任何请求 来源:Prosopo,这是纵深防御,即使有请求穿透了边缘层,源站也能兜底。

Hacker News 上,用户 austin-cheney 提出的思路是在安全层检查连接是否包含 Sec-Websocket-Key 头,有就直接丢弃这个 socket 来源:HN。这个方案不需要改 WAF 配置,在应用层就完成拦截,实现成本更低。

多源交叉验证:作者判断 vs 社区反驳

作者对这件事的判断很明确。“如果安全逻辑在 viewer-request 函数中,可能存在绕过方法” 来源:Prosopo。他认为这是个安全缺口,而且任何把安全逻辑放在 viewer-request 函数的站点都可能存在同样的洞。

austin-cheney 不同意。他的原话是“I don’t see the security problem. Everything looks like it’s operating correctly. If you don’t want to accept a WebSocket handshake then just drop the socket at your security layer if it contains the required Sec-Websocket-Key header.” 来源:HN。意思很直接,一切都在正常运行,如果不想要 WebSocket 握手,在安全层看到 Sec-WebSocket-Key 头就丢,问题就解决了。

两个人对问题的定义不一样。作者强调 CloudFront 接受 HTTP/1.1 且边缘函数看不到 Upgrade 头,所以必须在请求到达源站之前就阻断,这是 WAF 的思路。austin-cheney 认为升级请求本身不是问题,关键是显式拒绝,在安全层判断头部就够了 来源:HN。作者还提出让源站拒绝边缘函数未签名请求的纵深防御,评论者没提这个,但他的方案如果实现,效果类似。

我倾向于认为这是一次值得记录的配置盲区。CloudFront 的协议兼容性和 Lambda@Edge 的触发例外,让“每个请求都经过我的函数”这个假设失效了。austin-cheney 说得对,显式拒绝比依赖协议行为更可靠;作者说得也对,提前阻断是更稳妥的做法。我不确定哪种方案在所有场景下都成立,但至少现在我们知道,升级头不是一个可以忽略的字段。


原文:

A WebSocket upgrade bypassed our Lambda Edge · 来源:Hacker News

参考来源:

作者:itfan123 值班编辑 · 发布于 2026年11月2日

版权声明

所有资源都来源于爬虫采集,如有侵权请联系我们,我们将立即删除