Cloudflare 的 Web 应用程序防火墙中存在一个严重的零日漏洞,攻击者可以利用该漏洞绕过安全控制,并通过证书验证路径直接访问受保护的源服务器。

当 /.well-known/acme-challenge/ 路径下的请求绕过 WAF 规则时,问题就出现了。几乎所有现代网站上都存在这个专为机器而非人类设计的 URL。在证书颁发期间的几秒钟内,证书颁发机构的机器人会访问它来验证域名控制权。这本应是一项平淡无奇的例行任务,但在特定条件下,这个安静的路径却可能成为绕过安全控制的通道!
这篇报告将详细解析:针对该证书路径的流量如何能在应用的其他部分被客户规则阻止时,依然到达 Cloudflare 背后的源站;为什么这个问题至关重要;我们是如何谨慎验证这一点的;以及问题最终是如何被修复的。
ACME 协议的 60 秒入门
ACME 是证书颁发机构用于验证域名控制权的协议。在 HTTP-01 验证方法中,CA 期望你的网站在 /.well-known/acme-challenge/{token} 路径下提供一个一次性令牌。CA 会像普通客户端一样通过 HTTPS 获取该令牌;如果内容匹配,则颁发证书。其设计意图是严格且最小化的:仅让机器人读取特定路径下的一个小文件,仅此而已。ACME 通道本是为执行单一任务的机器人准备的,而不是让大量请求溜过守卫的旁路。
异常现象的发现
我们在审查一组应用程序的访问态势时,发现 WAF 被配置为阻止所有公共流量,只允许特定来源。在大多数路径下,WAF 都正常工作。但当我们将请求指向 /.well-known/acme-challenge/{token} 时,WAF 似乎退到了一边,由源站直接做出响应。这个响应主体的变化——从 Cloudflare 的拦截页面变为源站框架的页面——就是最初的线索。
为了排除租户特定配置错误的影响,我们在 Cloudflare 后面部署了受控的演示主机,这些主机默认对正常流量返回拦截页面:
- 在普通路径下,你会遇到 Cloudflare 的阻塞页面。
- 将相同的请求指向 ACME 挑战路径(使用任何令牌),你会得到源站生成的响应,通常是框架的 404 错误页面。
即使不查看响应头,这种差异也清晰可见:一个页面是 Cloudflare 风格的,另一个则明显来自后端应用程序。
可复现的验证信号
在演示主机上,我们使用小型、幂等的请求,并在令牌后附加一个无害的后缀(例如,在令牌后添加 /ae)来展示该行为无需真实的 ACME 文件即可触发。在每种情况下,我们在本应被 WAF 拦截的地方都收到了源站的直接响应。
以下是演示环境的代表性截图。第一张图片显示正常请求被 Cloudflare 的阻塞页面拦截。第二张显示我们用于阻塞演示中所有 cf- 主机名的自定义规则。接下来的三张显示每个演示主机在对 ACME 路径发起请求时,返回了由源站直接生成的 404 页面。
阻塞页面(正常请求)

自定义规则 - 阻塞 cf-* 主机名
在演示中,我们创建了一个规则,阻塞任何主机名包含 cf- 的请求。在生产环境中,许多团队会阻塞公共互联网,只允许公司 VPN 出口。此规则模拟了这种严格的访问控制态势。

源站 404 (Next.js)

源站 404 (Spring)

源站 404 (PHP)

如何获取稳定的挑战令牌用于测试
为了进行可重复的演示,我们需要一个不会中途失效的挑战令牌。Cloudflare 的 SSL/TLS 自定义主机名功能允许你管理指向你域名的第三方 CNAME 记录及其证书。我们添加了一个名为 cf-well-known.fearsoff.org 的自定义主机名,并明确选择了 HTTP 验证方式。下面的截图显示了添加流程和验证挂起的状态。


我们故意没有为 cf-well-known.fearsoff.org 创建 DNS 记录,因此证书颁发过程无限期保持挂起状态。在此状态下,Cloudflare 会显示验证机器人最终将请求的 HTTP-01 URL,例如:
http://cf-well-known.fearsoff.org/.well-known/acme-challenge/yMnWOcR2yv0yW-...Jm5QksreNRDUmqKfKPTk
我们没有完成验证,也没有在该路径放置任何挑战文件。我们的目标是为测试 WAF 行为锚定一个确定的、长期有效的令牌格式,而无需与真实的 CA 交互。获得这个令牌后,我们就可以在全球所有 Cloudflare 边缘节点上测试 /.well-known/acme-challenge/{token} 路径的访问行为。
为什么这个问题在实践中至关重要
WAF 控制旨在成为保护源站的前门。当单一维护路径绕过了这扇门,“内部”的边界定义就发生了移动。从实际意义上讲,/.well-known/acme-challenge/... 的信任边界从 WAF 滑向了源站本身。一旦源站变得从互联网可寻址——即使只通过这一条路由——普通的应用层漏洞就可能获得直接攻击路径,常规的错误页面也可能成为信息侦察的入口。
以下是我们演示中这种边界转变可能带来的具体风险。
Spring / Tomcat
在正常配置下,Actuator 等管理端点位于 WAF 和内部网络控制之后。通过 ACME 路径直达应用程序改变了这一安全边界。利用某些 Servlet 栈中著名的路径遍历技巧(..;/),请求可以落在 /actuator/env 等端点上,并返回进程环境和配置信息。这些数据通常包含敏感值——如数据库连接字符串、API 令牌、云密钥——这实质上扩大了源站中任何潜在漏洞的影响范围。

服务器端渲染框架通常会将服务器派生的值发送到客户端以“水合”页面。当 WAF 把守前门时,这是安全的。但当源站直接响应时,同一个页面可能会暴露出从未打算从公共互联网访问的操作细节,例如内部 API 密钥或配置。

PHP 应用路由
许多 PHP 应用程序通过 index.php 路由所有请求,并使用查询参数来选择视图。当这种模式存在本地文件包含漏洞时,公共可达性会将其转化为远程文件读取。请求 ../../../../etc/hosts 就足以证明其影响。在我们的演示中,即使是 404 错误处理流程也通过 index.php 路由,这就是为什么一旦源站开始直接响应,就可能暴露出额外的敏感文件内容。


这些演示只是后果,而非根本原因。核心问题在于 WAF 对特殊路径的决策逻辑。一旦这扇“门”被打开,源站内部任何脆弱的东西都突然变得只需一个请求即可触及。
不仅仅是 404:账户级 WAF 规则也被忽略
为了证明这不仅仅是绕道至框架的 404 页面,我们进一步配置了账户级 WAF 规则,用于拦截携带特定标记头部的请求。
- 在根路径
/ 下,带有 X-middleware-subrequest: 头部的请求会如预期被 WAF 拦截。
- 针对
/.well-known/acme-challenge/ 路径的相同请求(携带相同头部)却被允许通过,并由后端应用程序处理。
换句话说,本应阻止请求的账户级 WAF 规则对于 ACME 挑战路径下的请求未被评估。
为什么这个区别如此重要?许多真实的应用程序会基于 HTTP 头部做出安全或业务决策,或者将头部值传递给下游代码处理。当检查这些头部的 WAF 规则被跳过时,一整类安全问题重新获得了直达源站的路径,例如:
- 遗留代码中依赖头部值进行 SQL 连接。
- 通过
X-Forwarded-Host 或 X-Original-URL 头部触发的服务器端请求伪造和主机混淆漏洞。
- 当缓存键基于头部变化时,可能导致的缓存中毒。
- 使用
X-HTTP-Method-Override 头部进行 HTTP 方法覆盖的技巧。
- 连接到自定义头部以开启调试功能的开关。
一个显而易见的问题随之而来:有多少应用程序仍然过度信任 HTTP 头部?又有多少依赖 WAF 作为这种信任与互联网之间的最后防线?
漏洞原理与修复
我们调查期间的假设是:/.well-known/acme-challenge/ 路径下的请求在 Cloudflare 内部由不同的代码路径进行评估——这是一个隐式的例外,旨在协助证书颁发机构验证流程,但它的执行顺序可能位于客户自定义的阻塞控制之前。这可以解释为什么 ACME 路径下总是源站响应,而其他路径则显示拦截页面。
2025 年 10 月 27 日,Cloudflare 部署了修复程序。我们重新测试了相同的攻击模式,观察到了预期的行为:WAF 现在统一应用客户规则,包括针对 /.well-known/acme-challenge/ 路径的请求。这个曾经喧闹的路径,再次变得“无聊”且安全。
时间线
- 2025 年 10 月 9 日 - 通过 HackerOne 平台提交漏洞报告。
- 2025 年 10 月 13 日 - 供应商(Cloudflare)开始验证。
- 2025 年 10 月 14 日 - HackerOne 完成初步分诊。
- 2025 年 10 月 27 日 - 最终修复完成全球部署;重新测试确认问题已修复。
结语
最危险的安全漏洞往往始于那些看似例行公事的细节。证书验证机器人的专用通道,绝不应成为通往源站服务器的隐秘侧门。此次事件也提醒我们,在配置复杂的运维与安全规则时,需要持续关注边界条件和例外路径可能带来的风险。
参考链接:https://fearsoff.org/research/cloudflare-acme